REQTRACKER – A WEB-BASED REQUIREMENTS TRACKING TOOL Manpreet Singh Randhawa B.E., Punjab Engineering College, Chandigarh, India, 2004 PROJECT Submitted in partial satisfaction of the requirements for the degree of MASTER OF SCIENCE in SOFTWARE ENGINEERING at CALIFORNIA STATE UNIVERSITY, SACRAMENTO FALL 2009 © 2009 Manpreet Singh Randhawa ALL RIGHTS RESERVED ii REQTRACKER - A WEB-BASED REQUIREMENTS TRACKING TOOL A Project by Manpreet Singh Randhawa Approved by: __________________________________, Committee Chair Dr. Ahmed Salem ____________________________ Date __________________________________, Second Reader Dr. Jinsong Ouyang ____________________________ Date iii Student: Manpreet Singh Randhawa I certify that this student has met the requirements for format contained in the University format manual, and that this project is suitable for shelving in the Library and credit is to be awarded for the Project. __________________________, Graduate Coordinator Dr. Cui Zhang Department of Computer Science iv ___________________ Date Abstract of REQTRACKER - A WEB-BASED REQUIREMENTS TRACKING TOOL by Manpreet Singh Randhawa Based on the ‘2006 Chaos Report’ from The Standish Group, around 65% of the software development projects are not successful, 19% out of those are outright failures and 46% are challenged due to cost or time overruns [11]. In addition, nearly 40% of cancelled and delayed projects can be directly attributed to requirements [6]. Traditionally, requirements are stored in MS-Word documents or MS-Excel spreadsheets that make it very hard to track them and to make sure all the requirements have been accounted for, in all phases of Software Development Life Cycle (SDLC). This is one of the key reasons for unsatisfied requirements and hence failed projects. ReqTracker is a Web-based Requirements Tracking Tool that is designed to efficiently manage both functional and non-functional requirements throughout the SDLC. ReqTracker assists in simplification of software development process by ensuring satisfaction of all the requirements in all the phases of SDLC. ReqTracker assists in tracking all the changes in functional and nonfunctional requirements in all of the phases of SDLC. ReqTracker is a Java EE Web Application. This web application consists of three tiers: Client Tier, Presentation and Business Tier, and Resource Tier. v Client Tier: Everything in this tier deals with the communication with the user. It contains the user interface that is a Web Browser. Presentation and Business Tier: This tier contains the business logic of the application. It has the controller, the views and the model of the application. Resource Tier: This tier contains the application’s DBMS. , Committee Chair Dr. Ahmed Salem ______________________ Date vi To Ramanpreet vii ACKNOWLEDGMENTS Foremost, I would thank God – the almighty, for the grace bestowed upon me. Next, I would like to thank my Master Project Advisor, Dr. Ahmed Salem, whose knowledge, guidance, teaching and continuous support enabled me to successfully, complete my master’s project. Over the duration of the MS degree program, the knowledge I gained from his teaching and guidance has equipped me to contribute effectively to the Software Engineering community. I am grateful to him for his support and guidance. Next, I would like to thank my Master Project Second Reader, Dr. Jinsong Ouyang, who guided me throughout. His knowledge and valuable suggestions were necessary to ensure a successful project. I would also like to thank all the faculty members at CSU Sacramento for teaching me “Software Engineering”. Without their assistance and guidance, my Master’s degree would not have been completed successfully. In particular, I would like to thank Dr. Cui Zhang for her guidance, teaching, support, encouragement and advice. Apart from the valuable lessons taught by her in class, I learned several lessons for life as well from her. I am thankful to her for all that. Last but not the least; I would like to thank my fiancée Ramanpreet, my family and my friends for their support and encouragement. In particular, I would like to thank my brother, Gurmaninder for all his support, guidance and encouragement. His tireless efforts made all this possible. viii TABLE OF CONTENTS Page Dedication .............................................................................................................................. vii Acknowledgments................................................................................................................. viii List of Tables ............................................................................................................................ x List of Figures .......................................................................................................................... xi Chapter 1. INTRODUCTION .............................................................................................................. 1 1.1 Scope of the Development Project ........................................................................ 1 1.2 User Characteristics ............................................................................................... 3 1.3 Product Perspective................................................................................................ 4 2. THE NEED FOR DEVELOPING REQTRACKER .......................................................... 7 2.1 The Present Scenario............................................................................................. 7 2.2 Benefits of ReqTracker ......................................................................................... 9 3. REQUIREMENTS AND SPECIFICATION.................................................................... 11 3.1 Functional Requirements ..................................................................................... 11 3.2 Non-Functional Requirements ............................................................................. 24 3.3 Use Case Diagram ............................................................................................... 26 4. DESIGN AND IMPLEMENTATION.............................................................................. 28 4.1 Navigation Design ............................................................................................... 28 4.2 Architectural Design ............................................................................................ 29 4.3 Data Model Diagram............................................................................................ 30 4.4 User Interface Design .......................................................................................... 31 4.5 Database Design .................................................................................................. 47 5. CONCLUSION AND FUTURE WORK ......................................................................... 54 5.1 Conclusion ........................................................................................................... 54 5.2 Future Work ......................................................................................................... 55 Appendix A. Glossary .......................................................................................................... 57 Appendix B. Source Code .................................................................................................... 59 References ............................................................................................................................. 106 ix LIST OF TABLES Page 1. Table 4.1 – User Table ........................................................................................................ 47 2. Table 4.2 – Projects Table .................................................................................................. 47 3. Table 4.3 – Fnreq Table ...................................................................................................... 48 4. Table 4.4 – Design Table .................................................................................................... 49 5. Table 4.5 – Code Table ....................................................................................................... 50 6. Table 4.6 – Test Table ........................................................................................................ 51 7. Table 4.7 – Req_design Table ............................................................................................ 52 8. Table 4.8 – Req_code Table ............................................................................................... 52 9. Table 4.9 – Req_test Table ................................................................................................. 53 x LIST OF FIGURES Page 1. Figure 1.1 – Web-centric Application Architecture.............................................................. 4 2. Figure 1.2 – Detailed ReqTracker Architecture .................................................................... 5 3. Figure 3.1 – Use Case Diagram .......................................................................................... 27 4. Figure 4.1 – Navigation Design .......................................................................................... 28 5. Figure 4.2 – Architectural Design ....................................................................................... 29 6. Figure 4.3 – Data Model Diagram ...................................................................................... 30 7. Figure 4.4 – ReqTracker Home Page .................................................................................. 31 8. Figure 4.5 – Login Error ..................................................................................................... 32 9. Figure 4.6 – Create Project ................................................................................................. 33 10. Figure 4.7 – Manage Project ............................................................................................. 33 11. Figure 4.8 – Project Report HTML................................................................................... 34 12. Figure 4.9 – Project Report PDF....................................................................................... 34 13. Figure 4.10 – Create Functional Requirement .................................................................. 35 14. Figure 4.11 – Manage Functional Requirements .............................................................. 36 15. Figure 4.12 – View Functional Requirement Summary ................................................... 36 16. Figure 4.13 – Create Availability Requirement ................................................................ 37 17. Figure 4.14 – Create Modifiability/Performance Requirement ........................................ 38 18. Figure 4.15 – Create Security/Testability Requirement.................................................... 38 19. Figure 4.16 – Create Usability Requirement .................................................................... 39 20. Figure 4.17 – Manage Quality Requirements ................................................................... 39 21. Figure 4.18 – View Quality Requirement Summary ........................................................ 40 22. Figure 4.19 – Create Design Record ................................................................................. 41 23. Figure 4.20 – Manage Design Records ............................................................................. 41 24. Figure 4.21 – Operations on Design Records ................................................................... 42 25. Figure 4.22 – Upload New File Dialog ............................................................................. 42 26. Figure 4.23 – Create Code Record .................................................................................... 43 27. Figure 4.24 – Manage Code Records ................................................................................ 43 28. Figure 4.25 – Operations on Code Records ...................................................................... 44 29. Figure 4.26 – Create Test Record ..................................................................................... 44 xi 30. Figure 4.27 – Manage Test Records ................................................................................. 45 31. Figure 4.28 – Operations on Test Records ........................................................................ 45 32. Figure 4.29 – Admin Task Error Message ........................................................................ 46 33. Figure 4.30 – Create/Manage User Records ..................................................................... 46 xii 1 Chapter 1 INTRODUCTION 1.1 Scope of the Development Project ReqTracker is a Web-based Requirements Tracking Tool that is designed to efficiently manage both functional and non-functional requirements throughout the SDLC. ReqTracker assists in simplification of software development process by ensuring satisfaction of all the requirements in all the phases of SDLC. ReqTracker assists in tracking all the changes in functional and nonfunctional requirements in all of the phases of SDLC. Traditionally requirements are stored in MS-Word documents or MS-Excel spreadsheets that make it very hard to track them and to make sure all the requirements have been accounted for in Software Development Process. ReqTracker is a tool that can be used to simplify the software development process and provide an efficient way to manage a project's requirements during requirements analysis, designing, coding and testing phases in one environment. ReqTracker is a tool that provides complete traceability of requirements from inception to completion of project. In a normal flow of operation of ReqTracker, first, users register with ReqTracker to get an account on system. Once they have valid account information, they log in into the system and create a project. Then, for each project, users define project's requirement matrix based on the features and the quality the system needs to have. At that stage, ReqTracker helps users make sure they have the necessary requirements for the features and the quality they want in the system. ReqTracker also assists users in decomposing vague non-functional requirements to a level that is comprehensible by the developers and programmers. 2 Software Engineering Institute (SEI) at Carnegie Mellon University (CMU) has developed the method adopted by ReqTracker to clearly, define non-functional requirements [4]. Using this approach a six-step General Scenario is created for each of the Quality requirement. The six-steps include Source of Stimulus, Stimulus, Artifact, Environment, Response and Response Measure. ReqTracker assists users in developing quantifiable non-functional requirements for the six representative quality attributes viz. Availability, Modifiability, Performance, Security, Testability and Usability. Once non-functional requirements have been clearly specified using the General Scenarios, they can be easily implemented by developers and tested by testers. Each requirement is assigned a unique ID and stored in the database. Then the users develop design model(s) for each requirement. ReqTracker ties the design model with each requirement and users are asked to upload the design model(s) to the file system on the server. Later, users create module(s) (a functional code unit) corresponding to each design model (that is for each requirement). ReqTracker helps users make sure they have module(s) for each design model and ReqTracker ties these module(s) with design model(s) and ask users to upload these module(s) as well to the file system on the server. Finally, users create a test plan, consisting of several test cases. Each test case is mapped onto one or more requirements and ReqTracker ties those test cases to the requirements. These test cases too are uploaded to the file system on the server. ReqTracker helps ensure that all the requirements have been accounted for in design phase, implementation phase and testing phase. Once stakeholders clearly specify all the requirements for the software, ReqTracker makes sure that each requirement has been accounted for in requirements analysis, designing, coding and testing. Any test case that fails indicates a bug in the 3 system that needs to be resolved. ReqTracker also tracks which requirements have successfully passed all test cases and which have failed, thus takes care of tracking bugs and issues as well in software being developed. Whenever a change is made in any record related to a requirement, a flag is set in all corresponding records, indicating an action is needed on the part of the user. 1.2 User Characteristics The anticipated users of ReqTracker comprise of following: System Analysts – people who are responsible for gathering requirements from customer(s) and using ReqTracker to manage those. They are proficient in using complex software systems. System Designers – people who design software using the requirements captured by ReqTracker. They are proficient in using complex software systems. Software Developers – people who code the software based on the requirements captured by ReqTracker. They are proficient in using complex software systems. Test Engineers – people who test the software based on the requirements captured by ReqTracker. They are proficient in using complex software system. Managers – people who manage the software development project based on the requirements captured by ReqTracker. They feel comfortable in using a relatively easy to use user interface. So, for all of the users with this level of knowledge we need to keep a relatively easy to use user interface but with sufficient capability to allow expert IT professionals to perform their tasks. 4 1.3 Product Perspective ReqTracker is a Java Enterprise Edition (EE) Web Application. ReqTracker has a Web-centric Java EE Application Architecture as shown in Figure 1.1. This web application consists of three tiers: Client Tier, Presentation and Business Tier, and Resource Tier. Client Tier: Everything in this tier deals with the communication with the user. It contains the user interface that is a Web Browser. Presentation and Business Tier: This tier contains the business logic of the ReqTracker application. It has the controller, the views and the model of the ReqTracker application. Resources Tier: This tier contains the ReqTracker application’s DBMS. Figure 1.1 – Web-centric Application Architecture Figure 1.2 shows the detailed architecture for ReqTracker. Users of ReqTracker apply for an account on ReqTracker system and once they have the requisite account information, they can use the system from anywhere in the world, using Internet. Users provide information regarding the requirements (both functional and non-functional), design records, code records and test case records using the Graphical User Interface (GUI) of ReqTracker that is a web browser. 5 Figure 1.2 – Detailed ReqTracker Architecture Then, the User Interface (UI) manager of the ReqTracker system handles the incoming information and redirects it to the appropriate module manager. The incoming information is redirected to Requirements manager, Design manager, Implementation manager or Testing manager accordingly. The Requirements manager redirects information to Functional Requirement (FR) manager or Non-Functional Requirement (NFR) manager depending upon the type of requirement being created. Each of the module managers in addition, communicates with the file system on the server and a database. The record information is stored in the database. If a file is uploaded for a record, it is 6 stored on the file system on the server. Users can apply Create Read Update Delete (CRUD) operations on the information saved in the database. Users can download the files saved on the file system and they can upload new files corresponding to a record, after making requisite changes. Software System Environment Requirements: A user/client just needs to have a web browser, an internet connection and an active user account with ReqTracker in order to use the application. The server needs to have JDK 1.6 or higher, Glassfish v2 or higher for Application Server, and MySQL 5.0 for Database installed. The Application Server and the Database can be located on separate machines. 7 Chapter 2 THE NEED FOR DEVELOPING REQTRACKER 2.1 The Present Scenario Based on the ‘2006 Chaos Report’ from The Standish Group, around 65% of the software development projects are not successful, 19% out of those are outright failures and 46% are challenged due to cost or time overruns [11]. In addition, nearly 40% of cancelled and delayed projects can be directly attributed to requirements [6]. Traditionally, requirements are stored in MS-Word documents or MS-Excel spreadsheets that make it very hard to track them and to make sure all the requirements have been accounted for, in all phases of Software Development Life Cycle (SDLC). For instance, if a requirement has been created, there must be corresponding design record(s), code module(s) and test case(s) for that requirement. If that were not the case, certainly that requirement would not be satisfied. Furthermore, the non-functional requirements are the most troublesome ones. These are specified in very vague terms and it is almost impossible for developers to appropriately write code for these and extremely difficult for testers to test these [15]. For instance, a client might specify a non-functional requirement by saying, “The system must be secure”. That requirement is extremely hard to write code for and to test. It is written in a very ambiguous manner, and different people can have different interpretations for it. Moreover, whenever there is a change in any requirement or a related design, code or test case record, it is very hard to ensure corresponding changes are made in all the related records. For instance, if some change has been made in a design record for a requirement, corresponding 8 changes must also be made in requirement record, code record and test case record, as necessary. With the conventional means, it is very hard to ensure such actions are appropriately taken. Aforementioned are the key reasons for unsatisfied requirements and hence failed projects [3]. Several tools have been developed to address some of these issue but most of those are not being used for one reason or another. Several feature rich tools have been developed that can address the traceability of functional requirements throughout the SDLC. Some tools have been developed to address the traceability of non-functional requirements as well. None of the available tools helps to define non-functional requirements in quantifiable terms. None of the tools available addresses in one place, all the three issues viz. ensure there is design record(s), code module(s), and test case record(s) for each requirement; ensure change in any of the related records is reflected in all the related records; and assist users in defining non-functional requirements in quantifiable terms. Moreover, almost all the available tools are too expensive to be used by mid-sized and small-size companies. A representative list of such tools is provided below: OSRMT – Open Source Requirements Management Tool [12]. It is an effort in the same direction as ReqTracker. However, it lacks functionality, and quality. Most of its features do not work and non-functional requirements have not been satisfied for its development. Usability, availability, security of the tool is not good. Moreover, this tool does not address non-functional requirements and neither does it assist in requirement change tracking. o It is available at: http://sourceforge.net/projects/osrmt Optimal Trace – By Compuware [5]. It is a good tool that helps in management of requirements. It is one of very few tools, which address non-functional requirements. 9 However, it is very expensive for small and mid size businesses and most of such business cannot afford to use it. o It is available at: http://www.compuware.com/products/optimaltrace/ CASE Spec – By Goda Software [8]. It is a good requirements management tool. However, it does not address non-functional requirements. This tool too is very expensive for small businesses. o It is available at: http://www.analysttool.com/products.htm Lighthouse – By Workspace.com [17]. It is a nice web-based requirements management tool. However, like other such tools, it too does not address non-functional requirements and is too expensive for small businesses. o It is available at: http://www.workspace.com/ In addition, several other tools are available that are rich in features but are not affordable by midsize and small-size companies. Therefore, we can see there is a need for a tool that can address all the three issues viz. ensure there is design record(s), code module(s), and test case record(s) for each requirement; ensure change in any of the related records is reflected in all the related records; and assist users in defining non-functional requirements in quantifiable terms. In addition, such a tool must be affordable by companies of all sizes. Only then, quality software development can be expected. 2.2 Benefits of ReqTracker To cater to those needs, Manpreet Singh Randhawa has chosen to develop a tool – ReqTracker. ReqTracker is a freeware, web-based Requirements Tracking Tool that can be used for efficient management of both functional and non-functional requirements throughout the SDLC. 10 ReqTracker can be used to simplify the software development process and provide an efficient way to manage a project's requirements during requirements analysis, designing, implementation and testing phases, in one environment. ReqTracker provides functionality to ensure all the functional as well as non-functional requirements have been accounted for in the design phase, implementation (coding) phase and testing phase. ReqTracker assists users in developing quantifiable non-functional requirements. Software Engineering Institute (SEI) at Carnegie Mellon University (CMU) came up with a methodology to clearly, define non-functional requirements using six-part quality attribute scenarios [4]. ReqTracker utilizes that methodology to assist users in creating quantifiable and satisfiable quality requirements. In addition, ReqTracker has features that track all the changes in any of the related records viz. requirements, design records, code records and test case records. If there is any change in any of the related record an “action needed” flag is set in all the records. That gives an indication to the users to take an appropriate action in those records to conform to the changes made in a related record. Once users have made appropriate changes, they can reset the flags for individual records or for all the related records. Thus, we can see that ReqTracker caters to a real important need in the software community to assist people in software industry in creating quality software. ReqTracker is a web-based tool, so it can be accessed globally and it promotes team communication. Since, ReqTracker is a freeware tool, students, small-size companies and mid-size companies can effectively use it to create quality software. 11 Chapter 3 REQUIREMENTS AND SPECIFICATION This chapter contains a representative set of requirements for development of ReqTracker. Both functional and non-functional (quality) requirements have been listed in the following two sections. 3.1 Functional Requirements This section contains a representative set of functional requirements for the development of ReqTracker tool. 3.1.1 Sign Up on ReqTracker Allow a user to sign up for an account on ReqTracker system. The information required to sign up includes: a. The first and last name b. A valid email address c. A desirable username d. A desirable password 3.1.2 Log In Allow a user to log in into ReqTracker with valid credentials. Only registered users with valid username and password can log in into ReqTracker. 3.1.3 Log Out Allow user to log out of ReqTracker. Once user logs out, the session is destroyed and no one can access the system without logging in again. 3.1.4 Display Logged In Username Display for the users the username with which user logged in. 12 3.1.5 Display Selected Project and Selected Requirement Display for the user the project that is selected and the requirement that is selected. 3.1.6 Create New Project Allow a user to create a new project. User would provide the name for the new project. Project name does not have to be unique. 3.1.7 Manage Existing Project Display a table containing all the existing projects for the logged in user, along with the date when the project record was modified. Allow a user to manage an existing project by applying any of the following operations. a. Select Project Allow a user to select a project to work upon. b. Update Project Allow a user to update the information about a project. c. Delete Project Allow a user to delete an existing project. When a project is deleted, all the corresponding records and files viz. requirement records, design records, code records, test case records and project files on the file system are deleted as well. d. Generate HTML Report Allow a user to generate HTML report for the project that provides a list of all the functional and non-functional requirements along with important attributes. e. Generate PDF Report Allow a user to generate PDF report for the project that provides a list of all the functional and non-functional requirements along with important attributes. 3.1.8 Create a New Functional Requirement 13 Allow a user to create a new functional requirement. The information required to create a new functional requirement includes: a. Fn Req Number – the number assigned to the functional requirement. It is not an autogenerated field and users can choose any alphanumeric combination up to 15 characters in length. b. Fn Req Name – the name assigned to the functional requirement. c. Priority – the priority of the functional requirement. Critical, high, medium or low. d. Status – the status of the requirement. Requested, evaluated, planned, in progress, completed, or deferred. e. Author – the name of the person who created this requirement record. f. Fn Req Definition – the definition or description of the functional requirement. 3.1.9 Manage Existing Functional Requirements Allow a user to manage existing requirements. Display a table containing all the functional requirements for the selected project. The table must contain information regarding the following fields. Action Needed – whether user needs to take an action for updating that record or not Number – the Fn Req Number for that requirement Name – the Fn Req Name for that requirement Priority – the Priority for that requirement Status – the Status for that requirement Definition – the Fn Req Definition for that requirement Author – the name of the Author of that requirement Date Modified – the date when that requirement record was last modified Users can apply any of the following operations on the requirement records. 14 a. Select Requirement Allow a user to select a requirement to work upon. b. Update Requirement Allow a user to update the requirement record with new information. c. Delete Requirement Allow a user to delete a requirement record. All the related design records, code records and test case records get deleted as well. d. Reset Flags Allow a user to reset the “Action Needed” flags for all the records related to that requirement in one click. Action Needed flags get reset for that requirement record, related design records, code records and test case records. e. View Related Records Allow a user to click on the Fn Req Number hyperlink and view a summary of all the related design records, code records and test case records in a tabular format. The tables must display the following fields. Action Needed – indicates whether user needs to take an action or not to update that record. Number – contains the number assigned to that record Name – contains the name assigned to that record Author – contains the name of the author of the document used for that record Created By – contains the name of the person who created that record Date Modified – contains the date when the record was last time modified 3.1.10 Create a New Quality Requirement 15 Allow a user to create a new quality requirement. User can create a new Availability, Modifiability, Performance, Security, Testability, or Usability requirement. The information required to create a new functional requirement includes the following. (Note: the word quality is used to represent any of the six quality attribute names) a. Quality Req Number – the number assigned to the quality requirement. It is not an autogenerated field and users can choose any alphanumeric combination up to 15 characters in length. b. Quality Req Name – the name assigned to the quality requirement. c. Priority – the priority of the quality requirement. Critical, high, medium or low. d. Status – the status of the requirement. Requested, evaluated, planned, in progress, completed, or deferred. e. Author – the name of the person who created this requirement record. f. Source of Stimulus – this is some entity (a human, a computer system, or any other actuator) that generated the stimulus. g. Stimulus – the stimulus is a condition that needs to be considered when it arrives at a system. h. Environment – the stimulus occurs within certain conditions. The system may be in an overload condition or may be running when the stimulus occurs, or some other condition may be true. i. Artifact – some artifact is stimulated. This may be the whole system or some pieces of it. j. Response – the response is the activity undertaken after the arrival of the stimulus. k. Response Measure - when the response occurs, it should be measurable in some fashion so that the requirement can be tested. l. Response Measure Value – the value assigned to the selected response measure. m. Additional Info – additional information for the quality requirement. 3.1.11 Manage Existing Quality Requirements 16 Allow a user to manage existing requirements. Display a table containing all the quality requirements for the selected project. The table must contain information regarding the following fields. Action Needed – whether user needs to take an action for updating that record or not Type – the type of the quality requirement Number – the Quality Req Number for that requirement Name – the Quality Req Name for that requirement Priority – the Priority for that requirement Status – the Status for that requirement Additional Info – additional information or definition for that requirement Author – the name of the Author of that requirement Source – the source of stimulus for that requirement Stimulus – the stimulus for that requirement Artifact – the artifact for that requirement Environment – the environment for that requirement Response – the system response for that requirement Response Measure – the response measure for that requirement Response Measure Value – the response measure value for the selected response measure Date Modified – the date when that requirement record was last modified Users can apply any of the following operations on the requirement records. a. Select Requirement Allow a user to select a requirement to work upon. b. Update Requirement 17 Allow a user to update the requirement record with new information. c. Delete Requirement Allow a user to delete a requirement record. All the related design records, code records and test case records get deleted as well. d. Reset Flags Allow a user to reset the “Action Needed” flags for all the records related to that requirement in one click. Action Needed flags get reset for that requirement record, related design records, code records and test case records. e. View Related Records Allow a user to click on the Quality Req Number hyperlink and view a summary of all the related design records, code records and test case records in a tabular format. The tables must display the following fields. Action Needed – indicates whether user needs to take an action or not to update that record. Number – contains the number assigned to that record Name – contains the name assigned to that record Author – contains the name of the author of the document used for that record Created By – contains the name of the person who created that record Date Modified – contains the date when the record was last time modified 3.1.12 Use an Existing Design Record Allow users to attach an existing design record to a requirement. The existing design record created for any previous requirement of the project can be used exactly for another requirement. The advantage of doing this is that it is more space efficient and saves users the overhead of creating exactly same records repeatedly. 18 3.1.13 Create a New Design Record Allow a user to create a new design record for a requirement. The information required to create a new design record includes: a. Design Record Number – the number assigned to the design record. It is not an autogenerated field and users can choose any alphanumeric combination up to 15 characters in length. b. Design Record Name – the name assigned to the design record. c. Created By – the name of the author of the uploaded/ attached design document d. Author – the name of the person who created this design record. e. Existing Documents – the list of the existing design documents for a project that a user can choose to attach with a requirement. This avoids uploading the same document multiple times for different records. f. New Document – the location of the new design document being uploaded for a requirement. g. Description – the description of the design record wherein user specifies the exact section number and page number of the design document, which contains information about the new design record. Users can also provide any additional information about the design record. 3.1.14 Manage Existing Design Record Allow a user to manage existing design records. Display a table containing all the design records for the selected requirement. The table must contain information regarding the following fields. Action Needed – whether user needs to take an action for updating that record or not Number – the design record number Name – the design record name Description – the description for that design record Author – the name of the Author of that design record 19 Created By – the name of the author of the design document uploaded/ attached with the design record Date Modified – the date when that design record was last modified Users can apply any of the following operations on the design records. a. Upload Allow a user to upload a new/updated design document for that design record. b. Download Allow a user to download the design document attached with that design record. c. Update Allow a user to update the design record with new information. d. Delete Allow a user to delete a design record. e. Reset Flag Allow a user to reset the “Action Needed” flag for the design record. 3.1.15 Use an Existing Code Record Allow users to attach an existing code record to a requirement. The existing code record created for any previous requirement of the project can be used exactly for another requirement. The advantage of doing this is that it is more space efficient and saves users the overhead of creating exactly same records repeatedly. 3.1.16 Create a New Code Record Allow a user to create a new code record for a requirement. The information required to create a new code record includes: a. Code Record Number – the number assigned to the code record. It is not an auto- generated field and users can choose any alphanumeric combination up to 15 characters in length. 20 b. Code Record Name – the name assigned to the code record. c. Created By – the name of the author of the uploaded/ attached code document d. Author – the name of the person who created this code record. e. Existing Documents – the list of the existing code documents for a project that a user can choose to attach with a requirement. This avoids uploading the same document multiple times for different records. f. New Document – the location of the new code document being uploaded for a requirement. g. Description – the description of the code record wherein user specifies the exact section number and page number of the code document, which contains information about the new code record. Additional information can also be provided. 3.1.17 Manage Existing Code Record Allow a user to manage existing code records. Display a table containing all the code records for the selected requirement. The table must contain information regarding the following fields. Action Needed – whether user needs to take an action for updating that record or not Number – the code record number Name – the code record name Description – the description for that code record Author – the name of the Author of that code record Created By – the name of the author of the code document uploaded/ attached with the code record Date Modified – the date when that code record was last modified Users can apply any of the following operations on the code records. a. Upload 21 Allow a user to upload a new/updated code document for that code record. b. Download Allow a user to download the code document attached with that code record. c. Update Allow a user to update the code record with new information. d. Delete Allow a user to delete a code record. e. Reset Flag Allow a user to reset the “Action Needed” flag for the code record. 3.1.18 Use an Existing Test Case Record Allow users to attach an existing test case record to a requirement. The existing test case record created for any previous requirement of the project can be used exactly for another requirement. The advantage of doing this is that it is more space efficient and saves users the overhead of creating exactly same records repeatedly. 3.1.19 Create a New Test Case Record Allow a user to create a new test case record for a requirement. The information required to create a new test case record includes: a. Test Case Record Number – the number assigned to the test case record. It is not an autogenerated field and users can choose any alphanumeric combination up to 15 characters in length. b. Test Case Record Name – the name assigned to the test case record. c. Created By – the name of the author of the uploaded/ attached test case document d. Author – the name of the person who created this test case record. e. Existing Documents – the list of the existing test case documents for a project that a user can 22 choose to attach with a requirement. This avoids uploading the same document multiple times for different records. f. New Document – the location of the new test case document being uploaded for a requirement. g. Description – the description of the test case record wherein user specifies the exact section number and page number of the test case document, which contains information about the new test case record. 3.1.20 Manage Existing Test Case Records Allow a user to manage existing test case records. Display a table containing all the test case records for the selected requirement. The table contains the following information. Action Needed – whether user needs to take an action for updating that record or not Number – the test case record number Name – the test case record name Description – the description for that test case record Author – the name of the Author of that test case record Created By – the name of the author of the test case document uploaded/ attached with the test case record Date Modified – the date when that test case record was last modified Users can apply any of the following operations on the test case records. a. Upload Allow a user to upload a new/updated test case document for that test case record. b. Download Allow a user to download the test case document attached with that test case record. 23 c. Update Allow a user to update the test case record with new information. d. Delete Allow a user to delete a test case record. e. Reset Flag Allow a user to reset the “Action Needed” flag for the test case record. 3.1.21 Create a New User Record Allow a user with administrative privileges to create a new user account/record. The information required to create a new user record includes: a. Username – the desired, unique username for the new user b. Password – the desired password for the new user c. Administrator – the checkbox to indicate administrative privileges of the new user d. Active – the checkbox to indicate active status of the new user 3.1.22 Manage Existing User Records Allow a user with administrative privileges to manage existing user records. Display a table containing all the user records on the ReqTracker system. The table must contain information regarding the following fields. Username – the username of the user Password – the password of the user Admin – the administrative rights status of the user Active – the active status of the user Date Modified – the date when that user record was last modified Users can apply any of the following operations on the test case records. 24 a. Update Allow a user to update the user record with new information. b. Delete Allow a user to delete a user record. 3.2 Non-Functional Requirements This section contains a representative set of non-functional (quality) requirements for the development of ReqTracker tool. 3.2.1 End-User Software Compatibility ReqTracker must be compatible with a wide range of end user’s software environments. A representative list of software that ReqTracker must be compatible with is provided below. a. Operating Systems Windows 98 and above Macintosh OS X and above Linux (various flavors) b. Web Browsers Internet Explorer 6.0 and above Firefox 1.0 and above c. Tools ReqTracker can accept files made using any tool for uploading and storing on file system on server. 3.2.2 ReqTracker Usability ReqTracker needs to provide an easy-to-use user interface. In particular, it must address the following issues. 25 a. Intuitiveness: ReqTracker must provide an intuitive user interface that does not require extensive training for using the tool. b. No memorization: ReqTracker’s user interface must not require users to memorize commands and work flow in order to use the tool efficiently. c. Errors: The tool’s user interface should prevent users from making severe errors. In case users make an error, they must be able to recover from those easily. d. Consistency: The user interface must provide a consistent look and feel throughout. e. Satisfaction: The user interface must be pleasant to use and prevent annoyance of users to the greatest extent possible. 3.2.3 System Security Since the users would use this web application to save confidential and critical data of the projects, the security of ReqTracker is critical. System must ensure the three fundamental components of security are addressed. An efficient login/ logout facility can be used to ensure confidentiality, integrity and availability of the data. a. Confidentiality: System must ensure that the data of one project is kept confidential from unauthorized parties. Only authorized users with appropriate permission must be able to access the data. b. Integrity: System must ensure that the integrity of data is preserved. Only authorized user should be able to modify the data and no one else can modify data to any extent. c. Availability: System must ensure that authorized users are able to access their data whenever they need it. 3.2.4 System Performance 26 ReqTracker must provide services to users at a high performance. Users must not need to wait for more than 10 seconds for any command to complete execution, at peak load conditions and for more than 5 seconds under normal conditions. 3.2.5 System Modifiability System must be designed in a manner that aids in modifiability. Developers must be able to add a new feature (already developed) to the system within 24 person hours. 3.2.6 System Testability System must be designed to aid the testability of the system. The user interface must be testable by the end user within 30 minutes. The testers must be able to do black box testing on the system efficiently within 24 person hours. 3.3 Use Case Diagram The use case diagram for the ReqTracker system is shown in Figure 3.1. The major actors of the ReqTracker system includes the new users, who are trying to register with the ReqTracker system; the registered users, who already have an account with ReqTracker system; and the ReqTracker system administrators, who have full privileges on the system. 27 ReqTracker System UC1 - Sign Up * * UC2 - Add/Manage Users * New User UC3 - Log In/ Log Out * ** * ** Administrator * * * UC4 - Add/Manage Projects * * * UC5 - Add/Manage Requirements * * ** ** * * UC6 - Add/Manage Design Records * Registered User * * UC7 - Add/Manage Code Records * * UC8 - Add/Manage Test Records Figure 3.1 – Use Case Diagram 28 Chapter 4 DESIGN AND IMPLEMENTATION This chapter contains the major design models used for development of ReqTracker and the methodology employed for implementation of ReqTracker [7]. 4.1 Navigation Design Figure 4.1 shows the navigation design of ReqTracker system. The icon with “Home” represents the home page of ReqTracker system. The rectangular boxes represent the page elements pertaining to the major actions that users can perform on that page. The rounded corner boxes represent the various web pages present in ReqTracker system. The arrows represent the typical flow between the various pages. Since, ReqTracker is a web application there are multiple ways the various pages can be visited. The displayed paths represent the typical paths that are usually followed. Sign Up Log In Main Page Functional Requirement Design Records Quality Requirement Code Records Figure 4.1 – Navigation Design Admin Tasks Test Case Records 29 4.2 Architectural Design A pictorial representation of the architecture of the ReqTracker system in the form of a class diagram is presented in Figure 4.2. The major class attributes and operations are shown as well. User Project -Username -Password -Administrator -Active -DateModified +AddNewUser() +UpdateUser() +DeleteUser() * 1 -ProjectName -DateModified +AddProject() +UpdateProject() +DeleteProject() 1 1 * Design * * FunctionalRequirement -RequirementNumber -RequirementName -Priority -Status -Author -Description -DateModified -ActionNeeded +AddRequirement() +SelectRequirement() +UpdateRequirement() +DeleteRequirement() +ResetFlags() +ViewDetails() * * * Code * -CodeNumber -CodeName -Author -CreatedBy -Description -DocumentPath -DateModified +AddCode() +UseExistingRecord() +UpdateCode() +DeleteCode() +ResetFlag() +UploadDocument() +DownloadDocument() -DesignNumber -DesignName -Author -CreatedBy -Description -DocumentPath -DateModified +AddDesign() +UseExistingRecord() +UpdateDesign() +DeleteDesign() +ResetFlag() +UploadDocument() +DownloadDocument() QualityRequirement * * * * Test -TestNumber -TestName -Priority -Status -Author -CreatedBy * -Description -DocumentPath -DateModified +AddTest() +UseExistingRecord() +UpdateTest() +DeleteTest() +ResetFlag() +UploadDocument() +DownloadDocument() Figure 4.2 – Architectural Design -RequirementNumber -RequirementName -Priority -Status -Author -Description -DateModified -ActionNeeded -SourceOfStimulus -Stimulus -Artifact -Environment -Response -ResponseMeasure -ResponseMeasureValue +AddRequirement() +SelectRequirement() +UpdateRequirement() +DeleteRequirement() +ResetFlags() +ViewDetails() * * 30 4.3 Data Model Diagram Data model diagram of ReqTracker system is given below in Figure 4.3. The different data elements of ReqTracker system are shown below along with the relationships amongst them. The columns of the various entities are also shown in the figure. Fnreq Projects Users PK user_id PK project_id username password admin_status active_status creation_date FK1 user_id username project_name creation_date Req_code Req_design PK fnreq_id FK1 project_id user_id fnreq_num fnreq_name fnreq_priority fnreq_status fnreq_definition fnreq_author action_needed req_type qreq_type qreq_source qreq_stimulus qreq_artifact qreq_env qreq_response qreq_resp_msr qreq_resp_msr_value creation_date Req_test PK req_design_id PK req_code_id PK req_test_id FK2 FK1 design_id fnreq_id FK2 FK1 code_id fnreq_id FK2 FK1 test_id fnreq_id Test Design PK design_id design_doc_num design_doc_name design_doc_description design_doc_uploader design_doc_author design_doc_path action_needed creation_date Code PK PK test_id code_id code_doc_num code_doc_name code_doc_description code_doc_uploader code_doc_author code_doc_path action_needed creation_date Figure 4.3 – Data Model Diagram test_doc_num test_doc_name test_priority test_status test_doc_description test_doc_uploader test_doc_author test_doc_path action_needed creation_date 31 4.4 User Interface Design This section contains a description of the user interface design of the ReqTracker system. The user interface for the ReqTracker application is quite intuitive. The screens are easy to understand, the controls and links on the screen are self-explanatory. Several tool tips are provided on the buttons and links to guide the user. In order to use the User Interface of this application no training is required. It is very user friendly and quite simple. It is consistent throughout and requires no memorization. It encourages user to explore the interface and learn it without the fear of irreversible damage to the system. Meaningful error messages are provided throughout the interface to caution the user of impermissible actions. The following screens show the snap shots of various screens of the application. Figure 4.4 shows the home page of the ReqTracker application. Users need to provide valid username and password in order to use the application. Figure 4.4 – ReqTracker Home Page 32 Figure 4.5 shows the error messages and tool tips displayed on home page of the ReqTracker application. If users try to log in with invalid username and/or password they are shown descriptive error messages, dependant upon the error. The tool tip on the Sign Up link guides users for the Sign Up process. Clicking the Sign Up link takes users to their email client and enables them to register with the ReqTracker system. Figure 4.5 – Login Error If users provide a valid authentication they are taken to the Main Page of the ReqTracker application as shown in Figure 4.6. In this page, users can create a new project and manage existing projects. A user can create unlimited number of projects. A field on the page displays the name of the project a user has selected to work upon. User’s username is also displayed along with the various buttons for performing different actions in the application. 33 Figure 4.6 – Create Project Figure 4.7 shows the screen with controls for managing existing projects. A user may select a project to work upon, update information about a project, delete an existing project, view project report in HTML format, or view project report in a PDF format. Figure 4.7 – Manage Project 34 Figure 4.8 and Figure 4.9 show a sample project report in HTML format and PDF format respectively. The major attributes of each requirement are shown in the report. Requirements are categorized as functional and non-functional requirements. Figure 4.8 – Project Report HTML Figure 4.9 – Project Report PDF 35 Figure 4.10 shows a snapshot of Functional Requirement page of ReqTracker application. Users can create a new functional requirement in this page. A field displays the selected requirement. An error message is displayed if users try to perform some impermissible action, such as, trying to access Design/Code/Test Case page without selecting a requirement. Figure 4.10 – Create Functional Requirement Figure 4.11 shows a snapshot of Functional Requirement page wherein users can manage existing functional requirements. A table displays all the functional requirements for the selected project, along with the various attributes of those requirements. Users can perform various operations upon the requirements viz. select a requirement, update a requirement record, delete an existing requirement, reset flags for all the corresponding records of a requirement and view summary of all the design/ code/ test case records for a requirement. 36 Figure 4.11 – Manage Functional Requirements If users choose to view summary of the various design/ code/ test case records for a requirement, they are shown a page as displayed in Figure 4.12. The major attributes of the design/ code/ test case records for the selected requirement are displayed in this page. Figure 4.12 – View Functional Requirement Summary 37 Figure 4.13 shows the screen displayed when users visit Quality Requirement page. Users can create availability, modifiability, performance, security, testability or usability requirements in this page. Six-part quality attribute scenario, as prescribed by Software Engineering Institute, Carnegie Mellon University, is used in creation of various quality requirements. Users can choose from the various options for Source of Stimulus, Stimulus, Artifact, Environment, Response, and Response Measure for creating different quality requirements. Each quality attribute has unique values for all these six parts. The quality requirements created using this approach are clear, well defined, quantifiable, implementable, and testable. Figure 4.13 – Create Availability Requirement Figure 4.14 shows the screen displayed when users view the Quality Requirement page to create modifiability and performance requirements. The six-part quality attribute scenario options specific to the modifiability and performance requirements are shown in this section. 38 Figure 4.14 – Create Modifiability/Performance Requirement Figure 4.15 shows the screen displayed when users view the Quality Requirement page to create security and testability requirements. The six-part quality attribute scenario options specific to the security and testability requirements are shown in this section. Figure 4.15 – Create Security/Testability Requirement 39 Figure 4.16 shows the screen displayed when users view the Quality Requirement page to create usability requirements. In the Manage Existing Quality Requirements section, a table displays all the quality requirements for the selected project along with the various attributes. Figure 4.16 – Create Usability Requirement The various operations that can be performed on quality requirement records are displayed in Figure 4.17. The operations are essentially same as those on functional requirements. Figure 4.17 – Manage Quality Requirements 40 If users choose to view summary of the various design/ code/ test case records for a requirement, they are shown a page as displayed in Figure 4.18. The major attributes of the design/ code/ test case records for the selected requirement are displayed in this page. Figure 4.18 – View Quality Requirement Summary Figure 4.19 shows the Design Page of ReqTracker application. In this page, users can choose to use an exactly same, existing design record to attach with a requirement; create a new design record with an existing design document on the file system on server; or create a new design record by uploading a new design document on the file system on server. Users need to specify the exact details regarding design record, in the design document. Users do so by specifying the section number, page number and additional information regarding the design record in the Description area. 41 Figure 4.19 – Create Design Record Users can manage design records as well, in this page, as shown in Figure 4.20. A table displays all the design records along with their attributes. Users can update values for some of these attributes in this page. Figure 4.20 – Manage Design Records 42 Users can perform various operations on design records as shown in Figure 4.21. The operations that users can perform on design records include Download, Upload, Update, Delete and Reset Flag. Figure 4.21 – Operations on Design Records If users choose to upload a new file, a Choose File dialog box is displayed as shown in Figure 4.22. This dialog box is displayed when users click on the Browse button under the Upload field. Figure 4.22 – Upload New File Dialog 43 Figure 4.23 shows the Code Page of ReqTracker application. In this page, users can choose to use an exactly same, existing code record to attach with a requirement; create a new code record with an existing code document on the file system on server; or create a new code record by uploading a new code document on the file system on server. Figure 4.23 – Create Code Record Users can manage code records as well, in this page, as shown in Figure 4.24. A table displays all the code records along with their attributes. Users can update values for some of these attributes in this page. Figure 4.24 – Manage Code Records 44 Users can perform various operations on code records as shown in Figure 4.25. The operations that users can perform on code records include Download, Upload, Update, Delete and Reset Flag. Figure 4.25 – Operations on Code Records Figure 4.26 shows the Test Case Page of ReqTracker application. In this page, users can choose to use an exactly same, existing test case record to attach with a requirement; create a new test case record with an existing test case document on the file system on server; or create a new test case record by uploading a new test document on the file system on server. Figure 4.26 – Create Test Record 45 Users can manage code records as well, in this page, as shown in Figure 4.27. A table displays all the code records along with their attributes. Users can update values for some of these attributes in this page. Figure 4.27 – Manage Test Records Users can perform various operations on code records as shown in Figure 4.28. The operations that users can perform on test records include Download, Upload, Update, Delete and Reset Flag. Figure 4.28 – Operations on Test Records 46 If some user without administrative privileges tries to access Admin Tasks page, an error message is displayed as shown in Figure 4.29. Users are assigned administrative privileges by an administrator either during account creation or later on by updating the user information. Figure 4.29 – Admin Task Error Message Users with administrative privileges can access Admin Tasks page, as shown in Figure 4.30. Administrators can add a new user in the system or manage existing users. A table with a list of existing users is displayed. Administrators can update or delete existing user records. Figure 4.30 – Create/Manage User Records 47 4.5 Database Design This section contains a description of the database of ReqTracker system. Various tables of database of ReqTracker system are shown below along with various field names, attributes, etc. 4.5.1 User Table This table is used to store user information as shown in Table 4.1. The system generates the user_id field and it uniquely identifies each user. Each user is assigned a username and password that is used to log in into the ReqTracker system. Field Name Data Type user_id int(15) username password admin_status active_status creation_date varchar(30) varchar(30) boolean boolean Date Null/ Not Null System generated User Not Null ID Username Not Null Password Not Null Administrator or Not Not Null Active or Not Not Null Date when record Null modified Description Unique Keys Primary Key Table 4.1 – User Table 4.5.2 Projects Table This table is used to store project information as shown in Table 4.2. The system generates the project_id field and it uniquely identifies each project. User can choose any project name and it can be updated as well. Other fields cannot be created by user and are provided by the system. Field Name Data Type project_id int(15) user_id int(15) username varchar(30) project_name creation_date varchar(50) Date Null/ Not Null generated Not Null Description Unique Keys System Project ID User ID of user creating project Username of user creating project Name of the project Date when record modified Primary Key Table 4.2 – Projects Table Not Null Not Null Not Null Null Foreign Key 48 4.5.3 Fnreq Table Field Name Data Type fnreq_id int(15) project_id int(15) user_id int(15) fnreq_num varchar(15) fnreq_name varchar(50) fnreq_priority varchar(15) fnreq_status varchar(15) fnreq_definition varchar(200) fnreq_author varchar(20) action_needed varchar(5) req_type varchar(20) qreq_type varchar(20) qreq_source qreq_stimulus qreq_artifact qreq_env qreq_response qreq_resp_msr qreq_resp_msr_value varchar(100) varchar(100) varchar(100) varchar(100) varchar(100) varchar(100) varchar(100) creation_date Date Null/ Not Null System generated Not Null Requirement ID Project ID of selected Not Null project User ID of user Not Null creating requirement User selected Not Null requirement number Name of the Null requirement Priority of the Not Null requirement Status of the Not Null requirement Definition of the Null requirement Author of the Not Null requirement Field indicating Not Null whether user needs to take an action or not Field determining the Not Null type of requirement – functional or quality Field determining the Not Null type of quality requirement – availability, security, etc. Source of stimulus Not Null Stimulus Not Null Artifact Not Null Environment Not Null Response Not Null Response Measure Not Null Response Measure Not Null Value Date when record Null modified Description Table 4.3 – Fnreq Table Unique Keys Primary Key Foreign Key 49 This table stores functional and quality requirement information as shown in Table 4.3. The system generates the fnreq_id field and it uniquely identifies each requirement. Several fields are provided which are common to both functional and non-functional requirements. Some fields are used only with the non-functional requirements. These are pertaining to the six-part quality attribute general scenario description of non-functional requirements. 4.5.4 Design Table This table is used to store design record information as shown in Table 4.4. The system generates the design_id field and it uniquely identifies each design record. Other fields are used to describe a design record. Field Name Data Type design_id int(15) design_doc_num varchar(15) design_doc_name varchar(50) design_doc_description varchar(200) design_doc_uploader varchar(20) design_doc_author varchar(20) design_doc_path varchar(200) action_needed varchar(5) creation_date Date Null/ Not Null generated Not Null Description System Design ID User selected design record number Name of the design record Description of the design record Name of the person who created the uploaded design document Name of the person creating the design record Path where uploaded design document is stored Field indicating whether user needs to take an action or not Date when record modified Table 4.4 – Design Table Not Null Null Null Not Null Not Null Not Null Not Null Null Unique Keys Primary Key 50 4.5.5 Code Table This table is used to store code record information as shown in Table 4.5. The system generates the code_id field and it uniquely identifies each code record. Other fields are used to describe a code record. Field Name Data Type code_id int(15) code_doc_num varchar(15) code_doc_name varchar(50) code_doc_description varchar(200) code _doc_uploader varchar(20) code _doc_author varchar(20) code _doc_path varchar(200) action_needed varchar(5) creation_date Date Null/ Not Null generated Not Null Description System Code ID User selected code record number Name of the code record Description of the code record Name of the person who created the uploaded code document Name of the person creating the code record Path where uploaded code document is stored Field indicating whether user needs to take an action or not Date when record modified Unique Keys Primary Key Not Null Null Null Not Null Not Null Not Null Not Null Null Table 4.5 – Code Table 4.5.6 Test Table This table is used to store design record information as shown in Table 4.6. The system generates the test_id field and it uniquely identifies each test record. Other fields are used to describe a test record. This table is similar to Design Table and Code Table with a difference that this table includes information about priority and status of a test case record. 51 Field Name Data Type test_id int(15) test _doc_num varchar(15) test _doc_name varchar(50) test _doc_priority varchar(15) test _doc_status varchar(15) test _doc_description varchar(200) test _doc_uploader varchar(20) test _doc_author varchar(20) test _doc_path varchar(200) action_needed varchar(5) creation_date Date Null/ Not Null generated Not Null Description System Test ID User selected test record number Name of the test record Priority of the test record Status of the test record Description of the test record Name of the person who created the uploaded test document Name of the person creating the test record Path where uploaded test document is stored Field indicating whether user needs to take an action or not Date when record modified Unique Keys Primary Key Not Null Null Not Null Not Null Null Not Null Not Null Not Null Not Null Null Table 4.6 – Test Table 4.5.7 Req_design Table This table works as a mapping table between requirement table and design table as shown in Table 4.7. The system generates the req_design_id field and it uniquely identifies each requirement-design record mapping. This table contains the fnreq_id and the design_id that provide a mapping between each design record and a requirement. 52 Field Name Data Type req_design_id int(15) fnreq_id int(15) design_id int(15) Null/ Not Null System generated Not Null Req_design ID Primary key of Fnreq Not Null table Primary key of Design Not Null table Description Unique Keys Primary Key Foreign Key Foreign Key Table 4.7 – Req_design Table 4.5.8 Req_code Table This table works as a mapping table between requirement table and code table as it can be seen in Table 4.8. The system generates the req_code_id field and it uniquely identifies each requirement-code record mapping. This table contains the fnreq_id and the code_id that provide a mapping between each code record and a requirement. Field Name Data Type req_code_id int(15) fnreq_id int(15) code_id int(15) Null/ Not Null generated Not Null Description System Req_code ID Primary key of Fnreq Not Null table Primary key of Code Not Null table Unique Keys Primary Key Foreign Key Foreign Key Table 4.8 – Req_code Table 4.5.9 Req_test Table This table works as a mapping table between requirement table and test table as it can be seen in Table 4.9. The system generates the req_test_id field and it uniquely identifies each requirementtest record mapping. This table contains the fnreq_id and the test_id that provide a mapping between each test record and a requirement. 53 Field Name Data Type req_test_id int(15) fnreq_id int(15) test_id int(15) Null/ Not Null generated Not Null Description System Req_test ID Primary key of Fnreq Not Null table Primary key of Test Not Null table Table 4.9 – Req_test Table Unique Keys Primary Key Foreign Key Foreign Key 54 Chapter 5 CONCLUSION AND FUTURE WORK 5.1 Conclusion It has been realized that requirements account for the majority of failures of software development projects [6]. Affordable and efficient tool support for management of requirements is not available in market that can aid in development of quality software. ReqTracker is a tool that has been developed to cater to that need. ReqTracker is a freeware, webbased Requirements Tracking Tool that can be used for efficient management of both functional and non-functional requirements throughout the SDLC. ReqTracker can be used to simplify the software development process and provide an efficient way to manage a project's requirements during requirements analysis, designing, implementation and testing phases, in one environment. ReqTracker provides functionality to ensure all the functional as well as non-functional requirements have been accounted for in the design phase, implementation (coding) phase and testing phase. ReqTracker assists users in developing quantifiable non-functional requirements. Software Engineering Institute (SEI) at Carnegie Mellon University (CMU) came up with a methodology to clearly, define non-functional requirements using six-part quality attribute scenarios [4]. ReqTracker utilizes that methodology to assist users in creating quantifiable and satisfiable quality requirements. In addition, ReqTracker has features that track all the changes in any of the related records viz. requirements, design records, code records and test case records. Thus, we can see that ReqTracker caters to a real important need in the software community to assist people in software industry in creating quality software. ReqTracker is a web-based tool, so 55 it can be accessed globally and it promotes team communication. Since, ReqTracker is a freeware tool, students, small-size companies and mid-size companies can effectively use it to create quality software. 5.2 Future Work ReqTracker incorporates numerous features that make it a very efficient tool for managing requirements. However, the scope of the project prevented the addition of some features that would improve the utility of ReqTracker even further. Some of those features are listed below. ReqTracker can incorporate a built-in diagramming tool that would eliminate the need to upload the design diagrams. The built-in diagramming tool would assist users in developing the design drawings for the projects within ReqTracker. The design drawings that can be developed include UML drawings, data model diagrams, navigation designs, etc. ReqTracker can also incorporate a built-in text-formatting tool that would eliminate the need to upload the design documents, and test case documents. The text-formatting tool would assist users in editing the text within ReqTracker. It would include text-formatting features similar to MS Word, Open Office Writer, etc. In addition, ReqTracker can have some functionality to automatically, get the code from various IDEs such as NetBeans, Visual Studio, Eclipse, etc. That functionality would eliminate the need to upload the code documents. 56 Furthermore, ReqTracker can be integrated with other tools that manage requirements such as Requisite Pro, Caliber-RM, Optimal Trace, etc. ReqTracker can have functionality to import requirements from those tools. In addition, ReqTracker can be provided with functionality to extract requirements from Word documents as well. 57 APPENDIX A Glossary (Definitions, Acronyms, and Abbreviations) Abstraction A simplified representation of something that is potentially quite complex. Actor Represents anything that interacts with system. Attribute A description of the characteristics of the object; usually appears in OOA as adjectives. Class A description of a set of objects that share the same attributes operations, relationships, and semantics. Client User machine connected to server via Internet. DB Database EJB 3 Enterprise Java Beans 3 Entity A data object; producer/consumer of information outside the bounds of the system. HTML Hyper-Text Markup Language HW Hardware Intranet A private network inside a company or organization that uses the same kinds of software that you would find on the public Internet, but only for internal use. IEEE Institute of Electrical and Electronic Engineers Java EE Java Platform, Enterprise Edition JSF Java Server Faces 58 LAN Local Area Network Method A function (subroutine) associated with an object; usually appears in OOA as verbs. N/A Not Applicable OOA Object Oriented Analysis Object Referring to a software object, correlates to real-world object in that they, too, have state and behavior; usually appears in OOA as nouns, an instance of a class. PC Personal Computer SRS Software Requirements Specification SDD Software Design Document SDLC Software Development Life Cycle SW Software UML Unified Modeling Language Use Case A sequence of actions, including variants, that a system (or other entity) can perform, interacting with actors of the system. User The person who uses the ReqTracker application 59 APPENDIX B Source Code This section contains a representative set of source code for ReqTracker web application. Source code for ReqTracker web application is written using Java, JSP, JSF, and XML. FunctionalReq.jsp <?xml version="1.0" encoding="UTF-8"?> <!-Document : FunctionalReq Created on : Jun 12, 2009, 5:18:41 PM Author : Manpreet Singh Randhawa --> <jsp:root version="2.1" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:webuijsf="http://www.sun.com/webui/webuijsf"> <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/> <f:view> <webuijsf:page id="page1"> <webuijsf:html id="html1"> <webuijsf:head id="head1"> <webuijsf:link id="link1" url="/resources/stylesheet.css"/> </webuijsf:head> <webuijsf:body focus="form1:newNumberTF" id="body1" styleClass="reqTBody"> <center> <webuijsf:form id="form1"> <jsp:directive.include file="MasterFrag.jspf"/> <div align="center" id="reqTText"> <br/> <webuijsf:staticText binding="#{FunctionalReq.pageRedirectErrorST}" id="pageRedirectErrorST" styleClass="errorMsg" text="#{RequestBean1.errorMsg}"/> <br/> <br/> You are working on Project: <webuijsf:staticText binding="#{FunctionalReq.workingProjectST}" id="workingProjectST" style="color: #cc6600;" text="#{SessionBean1.workingProjectName}"/> <br/> You are working on Requirement: <webuijsf:staticText binding="#{FunctionalReq.workingReqST}" id="workingReqST" style="color: #cc6600;" text="#{SessionBean1.selectedFnReqNum}"/> (<webuijsf:staticText binding="#{FunctionalReq.reqType}" id="reqType" text="#{SessionBean1.reqType}"/>) </div> <div align="center" id="reqTText"> <br/> <h3>Create a New Functional Requirement</h3> 60 <webuijsf:staticText binding="#{FunctionalReq.fnReqNameErrorST}" id="fnReqNameErrorST" styleClass="errorMsg" text="#{RequestBean1.loginError}"/> <br/> <br/> <table border="0"> <tbody> <tr> <td align="right"> <webuijsf:textField binding="#{FunctionalReq.newNumberTF}" id="newNumberTF" label="Fn Req Number *" labelLevel="3" toolTip="Number For The Functional Requirement - Max 15 Characters"/> </td> <td align="right"> <webuijsf:textField binding="#{FunctionalReq.newNameTF}" id="newNameTF" label="Fn Req Name" labelLevel="3" toolTip="Name of The Functional Requirement Max 50 Characters"/> </td> </tr> <tr> <td align="right" style="height: 43px"> <webuijsf:dropDown binding="#{FunctionalReq.newPriorityDD}" id="newPriorityDD" items="#{FunctionalReq.newPriorityDDDefaultOptions.options}" label="Priority *"/> <webuijsf:dropDown binding="#{FunctionalReq.newStatusDD}" id="newStatusDD" items="#{FunctionalReq.newStatusDDDefaultOptions.options}" label="Status *"/> </td> <td align="right"> <webuijsf:textField binding="#{FunctionalReq.newAuthorTF}" id="newAuthorTF" label="Author *" toolTip="Name Of The Author Of The New Functional Requirement"/> </td> </tr> <tr> <td align="right" style="height: 66px"> <webuijsf:textArea binding="#{FunctionalReq.newDefinitionTA}" columns="30" id="newDefinitionTA" label="Fn Req Definition" rows="4" toolTip="Enter The Definition For The Functional Requirement - Max 200 Characters"/> </td> <td align="right"> <webuijsf:button actionExpression="#{FunctionalReq.createFnReqBtn_action}" id="createFnReqBtn" text="Create Requirement"/> </td> </tr> </tbody> </table> <br/> 61 <h3>Manage Existing Functional Requirements</h3> <br/> </div> <div id="reqTRDCTable"> <table border="0"> <thead> <tr> <th></th> </tr> </thead> <tbody> <tr> <td align="left"> <webuijsf:table augmentTitle="false" id="table1" paginateButton="true" paginationControls="true" title="Functional Requirements" width="0"> <webuijsf:tableRowGroup binding="#{FunctionalReq.tableRowGroup1}" id="tableRowGroup1" rows="5" sourceData="#{FunctionalReq.fnreqDataProvider}" sourceVar="currentRow"> <webuijsf:tableColumn headerText="Action Needed" id="tableColumn7" sort="fnreq.action_needed"> <webuijsf:staticText id="staticText7" text="#{currentRow.value['fnreq.action_needed']}"/> </webuijsf:tableColumn> <webuijsf:tableColumn headerText="Number" id="tableColumn1" sort="fnreq.fnreq_num"> <webuijsf:hyperlink actionExpression="#{FunctionalReq.reqDetailsLink_action}" id="reqDetailsLink" text="#{currentRow.value['fnreq.fnreq_num']}"/> </webuijsf:tableColumn> <webuijsf:tableColumn headerText="Name" id="tableColumn2" sort="fnreq.fnreq_name"> <webuijsf:textField id="textField1" text="#{currentRow.value['fnreq.fnreq_name']}"/> </webuijsf:tableColumn> <webuijsf:tableColumn headerText="Priority" id="tableColumn3" sort="fnreq.fnreq_priority"> <webuijsf:dropDown id="dropDown1" items="#{FunctionalReq.newPriorityDDDefaultOptions.options}" selected="#{currentRow.value['fnreq.fnreq_priority']}"/> </webuijsf:tableColumn> <webuijsf:tableColumn headerText="Status" id="tableColumn4" sort="fnreq.fnreq_status"> <webuijsf:dropDown id="dropDown2" items="#{FunctionalReq.newStatusDDDefaultOptions.options}" selected="#{currentRow.value['fnreq.fnreq_status']}"/> </webuijsf:tableColumn> <webuijsf:tableColumn headerText="Definition" id="tableColumn5" sort="fnreq.fnreq_definition"> <webuijsf:textArea id="textArea1" text="#{currentRow.value['fnreq.fnreq_definition']}"/> 62 </webuijsf:tableColumn> <webuijsf:tableColumn headerText="Author" id="tableColumn6" sort="fnreq.fnreq_author"> <webuijsf:textField id="textField2" text="#{currentRow.value['fnreq.fnreq_author']}"/> </webuijsf:tableColumn> <webuijsf:tableColumn headerText="Date Modified" id="tableColumn8" sort="fnreq.creation_date"> <webuijsf:staticText id="staticText8" text="#{currentRow.value['fnreq.creation_date']}"/> </webuijsf:tableColumn> <webuijsf:tableColumn id="updateDeleteColumn" width="40"> <webuijsf:button actionExpression="#{FunctionalReq.selectButton_action}" id="selectButton" text="Select"/> <webuijsf:button actionExpression="#{FunctionalReq.updateButton_action}" id="updateButton" text="Update"/> <webuijsf:button actionExpression="#{FunctionalReq.deleteButton_action}" id="deleteButton" text="Delete"/> <webuijsf:button actionExpression="#{FunctionalReq.resetFlagButton_action}" id="resetFlagButton" text="Reset Flags" toolTip="Click To Reset &quot;Action Needed&quot; Flags For&#xa;All Corresponding Records"/> <webuijsf:button actionExpression="#{FunctionalReq.designReportButton_action}" id="designReportButton" text="Des Report" toolTip="View A PDF Report For The Design Records"/> <webuijsf:button actionExpression="#{FunctionalReq.codeReportButton_action}" id="codeReportButton" text="Code Report" toolTip="View A PDF Report For The Code Records"/> <webuijsf:button actionExpression="#{FunctionalReq.testReportButton_action}" id="testReportButton" text="Test Report" toolTip="View A PDF Report For The Test Records"/> </webuijsf:tableColumn> </webuijsf:tableRowGroup> </webuijsf:table> </td> </tr> </tbody> </table> <br/> <br/> <br/> <br/> </div> </webuijsf:form> </center> </webuijsf:body> </webuijsf:html> </webuijsf:page> </f:view> 63 </jsp:root> FunctionalReq.java /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package reqtracker; import com.sun.data.provider.RowKey; import com.sun.data.provider.impl.CachedRowSetDataProvider; import com.sun.rave.web.ui.appbase.AbstractPageBean; import com.sun.sql.rowset.CachedRowSetXImpl; import com.sun.webui.jsf.component.Button; import com.sun.webui.jsf.component.DropDown; import com.sun.webui.jsf.component.StaticText; import com.sun.webui.jsf.component.TableRowGroup; import com.sun.webui.jsf.component.TextArea; import com.sun.webui.jsf.component.TextField; import com.sun.webui.jsf.model.DefaultTableDataProvider; import com.sun.webui.jsf.model.SingleSelectOptionsList; import java.sql.Connection; import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.HashMap; import java.util.Map; import java.util.Vector; import javax.faces.FacesException; import javax.faces.event.ValueChangeEvent; /** * <p>Page bean that corresponds to a similarly named JSP page. This * class contains component definitions (and initialization code) for * all components that you have defined on this page, as well as * lifecycle methods and event handlers where you may add behavior * to respond to incoming events.</p> * * @version FunctionalReq.java * @version Created on Jun 12, 2009, 5:18:41 PM * @author Manpreet Singh Randhawa */ public class FunctionalReq extends AbstractPageBean { // <editor-fold defaultstate="collapsed" desc="Managed Component Definition"> /** * <p>Automatically managed component initialization. <strong>WARNING:</strong> * This method is automatically generated, so any user-specified code inserted * here is subject to being replaced.</p> 64 */ private void _init() throws Exception { newStatusDDDefaultOptions.setOptions(new com.sun.webui.jsf.model.Option[]{new com.sun.webui.jsf.model.Option("Requested", "Requested"), new com.sun.webui.jsf.model.Option("Evaluated", "Evaluated"), new com.sun.webui.jsf.model.Option("Planned", "Planned"), new com.sun.webui.jsf.model.Option("In Progress", "In Progress"), new com.sun.webui.jsf.model.Option("Completed", "Completed"), new com.sun.webui.jsf.model.Option("Deferred", "Deferred")}); newPriorityDDDefaultOptions.setOptions(new com.sun.webui.jsf.model.Option[]{new com.sun.webui.jsf.model.Option("Critical", "Critical"), new com.sun.webui.jsf.model.Option("High", "High"), new com.sun.webui.jsf.model.Option("Medium", "Medium"), new com.sun.webui.jsf.model.Option("Low", "Low")}); codeDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.codeRowSet}")); codeRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); codeRowSet.setCommand("SELECT * FROM code"); codeRowSet.setTableName("code"); designDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.designRowSet}")); designRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); designRowSet.setCommand("SELECT ALL design.design_id, design.design_doc_num, design.design_doc_name, design.design_doc_description, design.design_doc_uploader, design.design_doc_author, design.design_doc_path, design.creation_date, design.action_needed FROM design"); designRowSet.setTableName("design"); projectsDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.projectsRowSet}")); projectsRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); projectsRowSet.setCommand("SELECT * FROM projects"); projectsRowSet.setTableName("projects"); req_codeDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.req_codeRowSet}")); req_codeRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); req_codeRowSet.setCommand("SELECT * FROM req_code"); req_codeRowSet.setTableName("req_code"); req_designDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.req_designRowSet}")); req_designRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); req_designRowSet.setCommand("SELECT * FROM req_design"); req_designRowSet.setTableName("req_design"); req_testDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.req_testRowSet}")); req_testRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); req_testRowSet.setCommand("SELECT * FROM req_test"); req_testRowSet.setTableName("req_test"); testDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.testRowSet}")); testRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); testRowSet.setCommand("SELECT * FROM test"); testRowSet.setTableName("test"); fnreqDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{SessionBean1.fnreqRowSet}")); 65 fnreqDataProvider1.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.fnreqRowSet}")); fnreqRowSet.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); fnreqRowSet.setCommand("SELECT ALL fnreq.fnreq_num, fnreq.fnreq_name, fnreq.fnreq_priority, fnreq.fnreq_status, fnreq.fnreq_author, fnreq.action_needed, fnreq.req_type, fnreq.qreq_type, fnreq.qreq_source, fnreq.qreq_stimulus, fnreq.qreq_artifact, fnreq.qreq_env, fnreq.qreq_response, fnreq.qreq_resp_msr, fnreq.qreq_resp_msr_value, fnreq.creation_date, fnreq.fnreq_definition FROM fnreq"); fnreqRowSet.setTableName("fnreq"); designDataProviderReport.setCachedRowSet((javax.sql.rowset.CachedRowSet) getValue("#{FunctionalReq.designRowSetReport}")); designRowSetReport.setDataSourceName("java:comp/env/jdbc/reqtdb_MySQL"); designRowSetReport.setCommand("SELECT ALL , design.design_doc_num, design.design_doc_name, design.design_doc_description, design.design_doc_uploader, design.design_doc_author, design.creation_date, design.action_needed, code.code_doc_num, code.code_doc_name, code.code_doc_description, code.code_doc_uploader, code.code_doc_author, code.creation_date, code.action_needed FROM design, code INNER JOIN req_design ON design.design_id = req_design.design_id INNER JOIN req_code ON code.code_id = req_code.code_id INNER JOIN fnreq ON fnreq.fnreq_id = req_design.req_id INNER JOIN fnreq ON fnreq.fnreq_id = req_code.req_id"); designRowSetReport.setTableName("design"); } private StaticText workingProjectST = new StaticText(); public StaticText getWorkingProjectST() { return workingProjectST; } public void setWorkingProjectST(StaticText st) { this.workingProjectST = st; } private DropDown existingFnReqDD = new DropDown(); public DropDown getExistingFnReqDD() { return existingFnReqDD; } public void setExistingFnReqDD(DropDown dd) { this.existingFnReqDD = dd; } private StaticText fnReqNameErrorST = new StaticText(); public StaticText getFnReqNameErrorST() { return fnReqNameErrorST; } public void setFnReqNameErrorST(StaticText st) { this.fnReqNameErrorST = st; } private TextArea newDefinitionTA = new TextArea(); public TextArea getNewDefinitionTA() { 66 return newDefinitionTA; } public void setNewDefinitionTA(TextArea ta) { this.newDefinitionTA = ta; } private TextField newAuthorTF = new TextField(); public TextField getNewAuthorTF() { return newAuthorTF; } public void setNewAuthorTF(TextField tf) { this.newAuthorTF = tf; } private TextField newNameTF = new TextField(); public TextField getNewNameTF() { return newNameTF; } public void setNewNameTF(TextField tf) { this.newNameTF = tf; } private TextField newNumberTF = new TextField(); public TextField getNewNumberTF() { return newNumberTF; } public void setNewNumberTF(TextField tf) { this.newNumberTF = tf; } private TableRowGroup tableRowGroup1 = new TableRowGroup(); public TableRowGroup getTableRowGroup1() { return tableRowGroup1; } public void setTableRowGroup1(TableRowGroup trg) { this.tableRowGroup1 = trg; } private SingleSelectOptionsList newStatusDDDefaultOptions = new SingleSelectOptionsList(); public SingleSelectOptionsList getNewStatusDDDefaultOptions() { return newStatusDDDefaultOptions; } public void setNewStatusDDDefaultOptions(SingleSelectOptionsList ssol) { this.newStatusDDDefaultOptions = ssol; } private DropDown newStatusDD = new DropDown(); 67 public DropDown getNewStatusDD() { return newStatusDD; } public void setNewStatusDD(DropDown dd) { this.newStatusDD = dd; } private SingleSelectOptionsList newPriorityDDDefaultOptions = new SingleSelectOptionsList(); public SingleSelectOptionsList getNewPriorityDDDefaultOptions() { return newPriorityDDDefaultOptions; } public void setNewPriorityDDDefaultOptions(SingleSelectOptionsList ssol) { this.newPriorityDDDefaultOptions = ssol; } private DropDown newPriorityDD = new DropDown(); public DropDown getNewPriorityDD() { return newPriorityDD; } public void setNewPriorityDD(DropDown dd) { this.newPriorityDD = dd; } private StaticText workingReqST = new StaticText(); public StaticText getWorkingReqST() { return workingReqST; } public void setWorkingReqST(StaticText st) { this.workingReqST = st; } private StaticText pageRedirectErrorST = new StaticText(); public StaticText getPageRedirectErrorST() { return pageRedirectErrorST; } public void setPageRedirectErrorST(StaticText st) { this.pageRedirectErrorST = st; } private CachedRowSetDataProvider codeDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getCodeDataProvider() { return codeDataProvider; } public void setCodeDataProvider(CachedRowSetDataProvider crsdp) { this.codeDataProvider = crsdp; 68 } private CachedRowSetXImpl codeRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getCodeRowSet() { return codeRowSet; } public void setCodeRowSet(CachedRowSetXImpl crsxi) { this.codeRowSet = crsxi; } private CachedRowSetDataProvider designDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getDesignDataProvider() { return designDataProvider; } public void setDesignDataProvider(CachedRowSetDataProvider crsdp) { this.designDataProvider = crsdp; } private CachedRowSetXImpl designRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getDesignRowSet() { return designRowSet; } public void setDesignRowSet(CachedRowSetXImpl crsxi) { this.designRowSet = crsxi; } private CachedRowSetDataProvider projectsDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getProjectsDataProvider() { return projectsDataProvider; } public void setProjectsDataProvider(CachedRowSetDataProvider crsdp) { this.projectsDataProvider = crsdp; } private CachedRowSetXImpl projectsRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getProjectsRowSet() { return projectsRowSet; } public void setProjectsRowSet(CachedRowSetXImpl crsxi) { this.projectsRowSet = crsxi; } private CachedRowSetDataProvider req_codeDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getReq_codeDataProvider() { return req_codeDataProvider; } 69 public void setReq_codeDataProvider(CachedRowSetDataProvider crsdp) { this.req_codeDataProvider = crsdp; } private CachedRowSetXImpl req_codeRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getReq_codeRowSet() { return req_codeRowSet; } public void setReq_codeRowSet(CachedRowSetXImpl crsxi) { this.req_codeRowSet = crsxi; } private CachedRowSetDataProvider req_designDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getReq_designDataProvider() { return req_designDataProvider; } public void setReq_designDataProvider(CachedRowSetDataProvider crsdp) { this.req_designDataProvider = crsdp; } private CachedRowSetXImpl req_designRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getReq_designRowSet() { return req_designRowSet; } public void setReq_designRowSet(CachedRowSetXImpl crsxi) { this.req_designRowSet = crsxi; } private CachedRowSetDataProvider req_testDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getReq_testDataProvider() { return req_testDataProvider; } public void setReq_testDataProvider(CachedRowSetDataProvider crsdp) { this.req_testDataProvider = crsdp; } private CachedRowSetXImpl req_testRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getReq_testRowSet() { return req_testRowSet; } public void setReq_testRowSet(CachedRowSetXImpl crsxi) { this.req_testRowSet = crsxi; } private CachedRowSetDataProvider testDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getTestDataProvider() { return testDataProvider; 70 } public void setTestDataProvider(CachedRowSetDataProvider crsdp) { this.testDataProvider = crsdp; } private CachedRowSetXImpl testRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getTestRowSet() { return testRowSet; } public void setTestRowSet(CachedRowSetXImpl crsxi) { this.testRowSet = crsxi; } private CachedRowSetDataProvider fnreqDataProvider = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getFnreqDataProvider() { return fnreqDataProvider; } public void setFnreqDataProvider(CachedRowSetDataProvider crsdp) { this.fnreqDataProvider = crsdp; } private StaticText reqType = new StaticText(); public StaticText getReqType() { return reqType; } public void setReqType(StaticText st) { this.reqType = st; } private CachedRowSetDataProvider fnreqDataProvider1 = new CachedRowSetDataProvider(); public CachedRowSetDataProvider getFnreqDataProvider1() { return fnreqDataProvider1; } public void setFnreqDataProvider1(CachedRowSetDataProvider crsdp) { this.fnreqDataProvider1 = crsdp; } private CachedRowSetXImpl fnreqRowSet = new CachedRowSetXImpl(); public CachedRowSetXImpl getFnreqRowSet() { return fnreqRowSet; } public void setFnreqRowSet(CachedRowSetXImpl crsxi) { this.fnreqRowSet = crsxi; } private CachedRowSetDataProvider designDataProviderReport = new CachedRowSetDataProvider(); 71 public CachedRowSetDataProvider getDesignDataProviderReport() { return designDataProviderReport; } public void setDesignDataProviderReport(CachedRowSetDataProvider crsdp) { this.designDataProviderReport = crsdp; } private CachedRowSetXImpl designRowSetReport = new CachedRowSetXImpl(); public CachedRowSetXImpl getDesignRowSetReport() { return designRowSetReport; } public void setDesignRowSetReport(CachedRowSetXImpl crsxi) { this.designRowSetReport = crsxi; } // </editor-fold> /** * <p>Construct a new Page bean instance.</p> */ public FunctionalReq() { } /** * <p>Callback method that is called whenever a page is navigated to, * either directly via a URL, or indirectly via page navigation. * Customize this method to acquire resources that will be needed * for event handlers and lifecycle methods, whether or not this * page is performing post back processing.</p> * * <p>Note that, if the current request is a postback, the property * values of the components do <strong>not</strong> represent any * values submitted with this request. Instead, they represent the * property values that were saved for this view when it was rendered.</p> */ @Override public void init() { // Perform initializations inherited from our superclass super.init(); // Perform application initialization that must complete // *before* managed components are initialized // TODO - add your own initialiation code here // <editor-fold defaultstate="collapsed" desc="Managed Component Initialization"> // Initialize automatically managed components // *Note* - this logic should NOT be modified try { _init(); } catch (Exception e) { log("FunctionalReq Initialization Failure", e); throw e instanceof FacesException ? (FacesException) e : new FacesException(e); 72 } // </editor-fold> // Perform application initialization that must complete // *after* managed components are initialized // TODO - add your own initialization code here fnreqDataProvider.refresh(); } /** * <p>Callback method that is called after the component tree has been * restored, but before any event processing takes place. This method * will <strong>only</strong> be called on a postback request that * is processing a form submit. Customize this method to allocate * resources that will be required in your event handlers.</p> */ @Override public void preprocess() { } /** * <p>Callback method that is called just before rendering takes place. * This method will <strong>only</strong> be called for the page that * will actually be rendered (and not, for example, on a page that * handled a postback and then navigated to a different page). Customize * this method to allocate resources that will be required for rendering * this page.</p> */ @Override public void prerender() { int pid = getSessionBean1().getWorkingProjectID(); String reqType = getSessionBean1().getSelectedReqType(); try { getSessionBean1().getFnreqRowSet().setObject(1, pid); getSessionBean1().getFnreqRowSet().setObject(2, reqType); // This doesn't work... //fnreqRowSet.setObject(1, pid); fnreqDataProvider.refresh(); } catch (Exception ex) { log("Error Description", ex); } 73 } /** * <p>Callback method that is called after rendering is completed for * this request, if <code>init()</code> was called (regardless of whether * or not this was the page that was actually rendered). Customize this * method to release resources acquired in the <code>init()</code>, * <code>preprocess()</code>, or <code>prerender()</code> methods (or * acquired during execution of an event handler).</p> */ @Override public void destroy() { codeDataProvider.close(); designDataProvider.close(); projectsDataProvider.close(); req_codeDataProvider.close(); req_designDataProvider.close(); req_testDataProvider.close(); testDataProvider.close(); fnreqDataProvider.close(); fnreqDataProvider1.close(); designDataProviderReport.close(); } /** * <p>Return a reference to the scoped data bean.</p> * * @return reference to the scoped data bean */ protected ApplicationBean1 getApplicationBean1() { return (ApplicationBean1) getBean("ApplicationBean1"); } /** * <p>Return a reference to the scoped data bean.</p> * * @return reference to the scoped data bean */ protected SessionBean1 getSessionBean1() { return (SessionBean1) getBean("SessionBean1"); } /** * <p>Return a reference to the scoped data bean.</p> * * @return reference to the scoped data bean */ protected RequestBean1 getRequestBean1() { 74 return (RequestBean1) getBean("RequestBean1"); } public void existingFnReqDD_processValueChange(ValueChangeEvent vce) { } // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // public String selectFnReqBtn_action() { // TODO: Replace with your code String currentReqNum = (String) existingFnReqDD.getSelected(); getSessionBean1().setSelectedFnReqNum(currentReqNum); int loggedUser = (Integer) getSessionBean1().getLoggedUserID(); RowKey[] fnreqArray = fnreqDataProvider.findAll("fnreq.fnreq_num", currentReqNum); for (int i = 0; i < fnreqArray.length; i++) { int currentUserId = (Integer) fnreqDataProvider.getValue("fnreq.user_id", fnreqArray[i]); if (loggedUser == currentUserId) { int currentFnReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", fnreqArray[i]); // selectedFnReqID variable is used for both functional and quality requirements. getSessionBean1().setSelectedFnReqID(currentFnReqId); break; }// end if }// end for existingFnReqDD.resetValue(); return null; } public String createFnReqBtn_action() { // TODO: Replace with your code String newReqNum = (String) newNumberTF.getText(); String newReqAuthor = (String) newAuthorTF.getText(); String errorMsg = " "; if (newReqNum == null || newReqAuthor == null) { errorMsg = "Please provide a Valid Requirement Number/ Author!"; getRequestBean1().setLoginError(errorMsg); newNumberTF.resetValue(); 75 newNameTF.resetValue(); newPriorityDD.resetValue(); newStatusDD.resetValue(); newAuthorTF.resetValue(); newDefinitionTA.resetValue(); return null; } else { if (fnreqDataProvider.canAppendRow()) { try { RowKey rowKey = fnreqDataProvider.appendRow(); fnreqDataProvider.setCursorRow(rowKey); // // // // // // // // // //// // // // // // Check if project name is unique or not RowKey testKey = fnreqDataProvider.findFirst("fnreq.fnreq_num", newReqNum); if (testKey != null) { errorMsg = "Sorry, this Requirement Number already exists in the system! " + "\nPlease select a different Requirement Number."; getRequestBean1().setLoginError(errorMsg); newNumberTF.resetValue(); return null; } int currentUid = (Integer) getSessionBean1().getLoggedUserID(); fnreqDataProvider.setValue("fnreq.user_id", rowKey, currentUid); int currentPid = (Integer) getSessionBean1().getWorkingProjectID(); fnreqDataProvider.setValue("fnreq.project_id", rowKey, currentPid); fnreqDataProvider.setValue("fnreq.fnreq_num", rowKey, newReqNum); String newReqName = (String) newNameTF.getText(); fnreqDataProvider.setValue("fnreq.fnreq_name", rowKey, newReqName); String newReqPriority = (String) newPriorityDD.getSelected(); fnreqDataProvider.setValue("fnreq.fnreq_priority", rowKey, newReqPriority); String newReqStatus = (String) newStatusDD.getSelected(); 76 fnreqDataProvider.setValue("fnreq.fnreq_status", rowKey, newReqStatus); String newReqDefinition = (String) newDefinitionTA.getText(); fnreqDataProvider.setValue("fnreq.fnreq_definition", rowKey, newReqDefinition); fnreqDataProvider.setValue("fnreq.fnreq_author", rowKey, newReqAuthor); fnreqDataProvider.setValue("fnreq.req_type", rowKey, "Functional"); java.util.Date date1 = new java.util.Date(); Date date = new Date(date1.getTime()); fnreqDataProvider.setValue("fnreq.creation_date", rowKey, date); fnreqDataProvider.setValue("fnreq.action_needed", rowKey, "No"); fnreqDataProvider.commitChanges(); fnreqDataProvider.refresh(); } catch (Exception e) { error("Cannot append new project: " + e); e.printStackTrace(); } } else { error("Cannot append a new row"); } newNumberTF.resetValue(); newNameTF.resetValue(); newPriorityDD.resetValue(); newStatusDD.resetValue(); newAuthorTF.resetValue(); newDefinitionTA.resetValue(); return null; } } public String updateButton_action() { // TODO: Replace with your code RowKey rowKey = tableRowGroup1.getRowKey(); 77 int currentReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); fnreqDataProvider.setCursorRow(rowKey); try { java.util.Date date1 = new java.util.Date(); Date date = new Date(date1.getTime()); fnreqDataProvider.setValue("fnreq.creation_date", rowKey, date); fnreqDataProvider.commitChanges(); fnreqDataProvider.refresh(); } catch (Exception e) { error("Cannot commit changes -- " + e); log("Exception: " + e); e.printStackTrace(); } // Prepare the req id vector for the current fnreq id Vector reqIdVect = new Vector(); reqIdVect.add(currentReqId); String flagValue = "Yes"; // Call method to set flags for all the required fields setActionFlags(reqIdVect, flagValue); return null; } public String deleteButton_action() { // TODO: Replace with your code RowKey rowKey = tableRowGroup1.getRowKey(); try { int selectedReqID = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); // Delete all the designs with that req id // Get rows for all the designs with currentReqID in req_design table RowKey[] desArray = req_designDataProvider.findAll("req_design.req_id", selectedReqID); // For each of those rows for (int j = 0; j < desArray.length; j++) { 78 // Get the design ID int currentDesignDelId = (Integer) req_designDataProvider.getValue("req_design.design_id", desArray[j]); try { //RowKey dDocsKey = req_designDataProvider.findFirst("design.design_doc_num", currentDDocNum); RowKey[] reqDesArray = req_designDataProvider.findAll("req_design.design_id", currentDesignDelId); for (int k = 0; k < reqDesArray.length; k++) { int foundReqId = (Integer) req_designDataProvider.getValue("req_design.req_id", reqDesArray[k]); if (foundReqId == selectedReqID) { req_designDataProvider.removeRow(reqDesArray[k]); req_designDataProvider.commitChanges(); break; } } req_designDataProvider.refresh(); reqDesArray = req_designDataProvider.findAll("req_design.design_id", currentDesignDelId); if (reqDesArray.length == 0) { RowKey designRowKey = designDataProvider.findFirst("design.design_id", currentDesignDelId); designDataProvider.removeRow(designRowKey); designDataProvider.commitChanges(); } designDataProvider.refresh(); } catch (Exception e) { error("Cannot delete design with row key " + rowKey + e); } } 79 // Delete all the codes with that req id // Get rows for all the codes with currentReqID in req_code table RowKey[] codeArray = req_codeDataProvider.findAll("req_code.req_id", selectedReqID); // For each of those rows for (int j = 0; j < codeArray.length; j++) { // Get the code ID int currentCodeId = (Integer) req_codeDataProvider.getValue("req_code.code_id", codeArray[j]); try { //RowKey dDocsKey = req_designDataProvider.findFirst("design.design_doc_num", currentDDocNum); RowKey[] reqCodeArray = req_codeDataProvider.findAll("req_code.code_id", currentCodeId); for (int k = 0; k < reqCodeArray.length; k++) { int foundReqId = (Integer) req_codeDataProvider.getValue("req_code.req_id", reqCodeArray[k]); if (foundReqId == selectedReqID) { req_codeDataProvider.removeRow(reqCodeArray[k]); req_codeDataProvider.commitChanges(); break; } } req_codeDataProvider.refresh(); reqCodeArray = req_codeDataProvider.findAll("req_code.code_id", currentCodeId); if (reqCodeArray.length == 0) { RowKey codeRowKey = codeDataProvider.findFirst("code.code_id", currentCodeId); codeDataProvider.removeRow(codeRowKey); codeDataProvider.commitChanges(); } codeDataProvider.refresh(); 80 } catch (Exception e) { error("Cannot delete code with row key " + rowKey + e); } } // Delete all the tests with that req id // Get rows for all the designs with currentReqID in req_test table RowKey[] testArray = req_testDataProvider.findAll("req_test.req_id", selectedReqID); // For each of those rows for (int j = 0; j < testArray.length; j++) { // Get the test ID int currentTestId = (Integer) req_testDataProvider.getValue("req_test.test_id", testArray[j]); try { //RowKey dDocsKey = req_designDataProvider.findFirst("design.design_doc_num", currentDDocNum); RowKey[] reqTestArray = req_testDataProvider.findAll("req_test.test_id", currentTestId); for (int k = 0; k < reqTestArray.length; k++) { int foundReqId = (Integer) req_testDataProvider.getValue("req_test.req_id", reqTestArray[k]); if (foundReqId == selectedReqID) { req_testDataProvider.removeRow(reqTestArray[k]); req_testDataProvider.commitChanges(); break; } } req_testDataProvider.refresh(); reqTestArray = req_testDataProvider.findAll("req_test.test_id", currentTestId); if (reqTestArray.length == 0) { RowKey testRowKey = testDataProvider.findFirst("test.test_id", currentTestId); testDataProvider.removeRow(testRowKey); 81 testDataProvider.commitChanges(); } testDataProvider.refresh(); } catch (Exception e) { error("Cannot delete test case with row key " + rowKey + e); } } fnreqDataProvider.removeRow(rowKey); fnreqDataProvider.commitChanges(); fnreqDataProvider.refresh(); } catch (Exception e) { error("Cannot delete project with row key " + rowKey + e); } return null; } public String reqDetailsLink_action() { // TODO: Process the action. Return value is a navigation // case name where null will return to the same page. RowKey rowKey = tableRowGroup1.getRowKey(); fnreqDataProvider.setCursorRow(rowKey); int currentFnReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); getSessionBean1().setTableSelectReqID(currentFnReqId); getSessionBean1().setSelectedFnReqID(currentFnReqId); String currentReqNum = (String) fnreqDataProvider.getValue("fnreq.fnreq_num", rowKey); getSessionBean1().setSelectedFnReqNum(currentReqNum); getSessionBean1().setReqType("Functional"); return "reqDetailPg"; } public String selectButton_action() { // TODO: Replace with your code RowKey rowKey = tableRowGroup1.getRowKey(); 82 fnreqDataProvider.setCursorRow(rowKey); int currentFnReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); // selectedFnReqID variable is used for both functional and quality requirements. getSessionBean1().setTableSelectReqID(currentFnReqId); getSessionBean1().setSelectedFnReqID(currentFnReqId); String currentReqNum = (String) fnreqDataProvider.getValue("fnreq.fnreq_num", rowKey); getSessionBean1().setSelectedFnReqNum(currentReqNum); getSessionBean1().setReqType("Functional"); return null; } public void setActionFlags(Vector reqIdVect, String flagVal) { fnreqDataProvider.refresh(); designDataProvider.refresh(); req_designDataProvider.refresh(); codeDataProvider.refresh(); req_codeDataProvider.refresh(); testDataProvider.refresh(); req_testDataProvider.refresh(); String flagValue = flagVal; // Set flags for requirements for (int i = 0; i < reqIdVect.size(); i++) { int currentReqId = (Integer) reqIdVect.get(i); RowKey currReqKey = fnreqDataProvider.findFirst("fnreq.fnreq_id", currentReqId); fnreqDataProvider.setValue("fnreq.action_needed", currReqKey, flagValue); fnreqDataProvider.commitChanges(); fnreqDataProvider.refresh(); } // Set flags for designs for (int i = 0; i < reqIdVect.size(); i++) { int currentReqId = (Integer) reqIdVect.get(i); RowKey[] reqDesArray = req_designDataProvider.findAll("req_design.req_id", currentReqId); 83 for (int j = 0; j < reqDesArray.length; j++) { //RowKey currDesKey = req_designDataProvider.findFirst("req_design.design_id", reqDesArray[j]); designDataProvider.setValue("design.action_needed", reqDesArray[j], flagValue); designDataProvider.commitChanges(); designDataProvider.refresh(); } } // Set flags for codes for (int i = 0; i < reqIdVect.size(); i++) { int currentReqId = (Integer) reqIdVect.get(i); RowKey[] reqCodeArray = req_codeDataProvider.findAll("req_code.req_id", currentReqId); for (int j = 0; j < reqCodeArray.length; j++) { //RowKey currCodeKey = req_codeDataProvider.findFirst("req_code.code_id", reqCodeArray[j]); codeDataProvider.setValue("code.action_needed", reqCodeArray[j], flagValue); codeDataProvider.commitChanges(); codeDataProvider.refresh(); } } // Set flags for tests for (int i = 0; i < reqIdVect.size(); i++) { int currentReqId = (Integer) reqIdVect.get(i); RowKey[] reqTestArray = req_testDataProvider.findAll("req_test.req_id", currentReqId); for (int j = 0; j < reqTestArray.length; j++) { //RowKey currTestKey = req_testDataProvider.findFirst("req_test.test_id", reqTestArray[j]); testDataProvider.setValue("test.action_needed", reqTestArray[j], flagValue); testDataProvider.commitChanges(); 84 testDataProvider.refresh(); } } } public String resetFlagButton_action() { // TODO: Replace with your code RowKey rowKey = tableRowGroup1.getRowKey(); // Prepare the req id vector for the current fnreq id int selectedReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); Vector reqIdVect = new Vector(); reqIdVect.add(selectedReqId); String flagValue = "No"; // Call method to set flags for all the required fields setActionFlags(reqIdVect, flagValue); return null; } public String designReportButton_action() { // TODO: Replace with your code RowKey rowKey = tableRowGroup1.getRowKey(); int selectedReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); String JDBC_DRIVER = "com.mysql.jdbc.Driver"; String DATABASE_URL = "jdbc:mysql://athena.ecs.csus.edu/reqtdb"; String USERNAME = "reqtdb"; String PASSWORD = "reqtdb"; Connection conn = null; ResultSet rs = null; try { if (conn == null) { System.out.println("Reaching here in jdbcutil"); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://athena.ecs.csus.edu/reqtdb?user=" + USERNAME + "&password=" + PASSWORD; System.out.println("URL is " + url); conn = DriverManager.getConnection(url); 85 System.out.println("Connection successful"); String sqlQue = "SELECT ALL design.design_doc_num, design.design_doc_name, design.design_doc_description, design.design_doc_uploader, design.design_doc_author, design.creation_date, design.action_needed FROM design INNER JOIN req_design ON design.design_id = req_design.design_id INNER JOIN fnreq ON req_design.req_id = fnreq.fnreq_id WHERE fnreq.fnreq_id = ? "; //" SELECT ALL code.code_doc_num, code.code_doc_name, code.code_doc_description, code.code_doc_uploader, code.code_doc_author, code.creation_date, code.action_needed FROM code INNER JOIN req_code ON code.code_id = req_code.code_id INNER JOIN fnreq ON req_code.req_id = fnreq.fnreq_id WHERE fnreq.fnreq_id = ?"; System.out.println("SQL Statement is " + sqlQue); PreparedStatement ps = conn.prepareStatement(sqlQue); ps.setInt(1, selectedReqId); rs = ps.executeQuery(); // String sqlQuerry = "SELECT ALL design.design_doc_num, design.design_doc_name, design.design_doc_description, design.design_doc_uploader, design.design_doc_author, design.creation_date, design.action_needed FROM design INNER JOIN req_design ON design.design_id = req_design.design_id INNER JOIN fnreq ON fnreq.fnreq_id = req_design.req_id"; // Statement s = conn.createStatement(); // rs = s.executeQuery(sqlQuerry); } } catch (Exception e) { System.out.println("Connection unsuccessful"); e.printStackTrace(); } // Free up the rowset resources fnreqDataProvider.close(); Map fillParams = new HashMap(); try { fillParams.put("LogoURL", getExternalContext().getResource("/resources/ReqTracker.gif")); getApplicationBean1().jasperReport("designReport", "application/pdf", rs, fillParams); } catch (Exception e) { log("Exception generating report", e); error("Exception generating report: " + e); } try { // TODO: Insert logic that may cause an exception // for example, performing database logic or file access conn.close(); 86 } catch (Exception e) { // print exception information in the server log log("Exception closing connection!!!", e); } return null; } public String codeReportButton_action() { // TODO: Replace with your code RowKey rowKey = tableRowGroup1.getRowKey(); int selectedReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); String JDBC_DRIVER = "com.mysql.jdbc.Driver"; String DATABASE_URL = "jdbc:mysql://athena.ecs.csus.edu/reqtdb"; String USERNAME = "reqtdb"; String PASSWORD = "reqtdb"; Connection conn = null; ResultSet rs = null; try { if (conn == null) { System.out.println("Reaching here in jdbcutil"); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://athena.ecs.csus.edu/reqtdb?user=" + USERNAME + "&password=" + PASSWORD; System.out.println("URL is " + url); conn = DriverManager.getConnection(url); System.out.println("Connection successful"); String sqlQue = " SELECT ALL code.code_doc_num, code.code_doc_name, code.code_doc_description, code.code_doc_uploader, code.code_doc_author, code.creation_date, code.action_needed FROM code INNER JOIN req_code ON code.code_id = req_code.code_id INNER JOIN fnreq ON req_code.req_id = fnreq.fnreq_id WHERE fnreq.fnreq_id = ?"; System.out.println("SQL Statement is " + sqlQue); PreparedStatement ps = conn.prepareStatement(sqlQue); ps.setInt(1, selectedReqId); rs = ps.executeQuery(); // String sqlQuerry = "SELECT ALL design.design_doc_num, design.design_doc_name, design.design_doc_description, design.design_doc_uploader, design.design_doc_author, design.creation_date, design.action_needed FROM design INNER JOIN req_design ON 87 design.design_id = req_design.design_id INNER JOIN fnreq ON fnreq.fnreq_id = req_design.req_id"; // Statement s = conn.createStatement(); // rs = s.executeQuery(sqlQuerry); } } catch (Exception e) { System.out.println("Connection unsuccessful"); e.printStackTrace(); } // Free up the rowset resources fnreqDataProvider.close(); Map fillParams = new HashMap(); try { fillParams.put("LogoURL", getExternalContext().getResource("/resources/ReqTracker.gif")); getApplicationBean1().jasperReport("codeReport", "application/pdf", rs, fillParams); } catch (Exception e) { log("Exception generating report", e); error("Exception generating report: " + e); } try { // TODO: Insert logic that may cause an exception // for example, performing database logic or file access conn.close(); } catch (Exception e) { // print exception information in the server log log("Exception closing connection!!!", e); } return null; } public String testReportButton_action() { // TODO: Replace with your code RowKey rowKey = tableRowGroup1.getRowKey(); int selectedReqId = (Integer) fnreqDataProvider.getValue("fnreq.fnreq_id", rowKey); String JDBC_DRIVER = "com.mysql.jdbc.Driver"; String DATABASE_URL = "jdbc:mysql://athena.ecs.csus.edu/reqtdb"; String USERNAME = "reqtdb"; String PASSWORD = "reqtdb"; Connection conn = null; ResultSet rs = null; 88 try { if (conn == null) { System.out.println("Reaching here in jdbcutil"); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://athena.ecs.csus.edu/reqtdb?user=" + USERNAME + "&password=" + PASSWORD; System.out.println("URL is " + url); conn = DriverManager.getConnection(url); System.out.println("Connection successful"); String sqlQue = " SELECT ALL test.test_doc_num, test.test_doc_name, test.test_doc_description, test.test_doc_uploader, test.test_doc_author, test.creation_date, test.action_needed FROM test INNER JOIN req_test ON test.test_id = req_test.test_id JOIN fnreq ON req_test.req_id = fnreq.fnreq_id WHERE fnreq.fnreq_id = ?"; System.out.println("SQL Statement is " + sqlQue); PreparedStatement ps = conn.prepareStatement(sqlQue); ps.setInt(1, selectedReqId); rs = ps.executeQuery(); // String sqlQuerry = "SELECT ALL design.design_doc_num, design.design_doc_name, design.design_doc_description, design.design_doc_uploader, design.design_doc_author, design.creation_date, design.action_needed FROM design INNER JOIN req_design ON design.design_id = req_design.design_id INNER JOIN fnreq ON fnreq.fnreq_id = req_design.req_id"; // Statement s = conn.createStatement(); // rs = s.executeQuery(sqlQuerry); } } catch (Exception e) { System.out.println("Connection unsuccessful"); e.printStackTrace(); } // Free up the rowset resources fnreqDataProvider.close(); Map fillParams = new HashMap(); try { fillParams.put("LogoURL", getExternalContext().getResource("/resources/ReqTracker.gif")); getApplicationBean1().jasperReport("testReport", "application/pdf", rs, fillParams); } catch (Exception e) { log("Exception generating report", e); error("Exception generating report: " + e); } INNER 89 try { // TODO: Insert logic that may cause an exception // for example, performing database logic or file access conn.close(); } catch (Exception e) { // print exception information in the server log log("Exception closing connection!!!", e); } return null; } } faces-config.xml <?xml version='1.0' encoding='UTF-8'?> <!-- =========== FULL CONFIGURATION FILE ================================== --> <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/webfacesconfig_1_2.xsd"> <managed-bean> <managed-bean-name>SessionBean1</managed-bean-name> <managed-bean-class>reqtracker.SessionBean1</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>ApplicationBean1</managed-bean-name> <managed-bean-class>reqtracker.ApplicationBean1</managed-bean-class> <managed-bean-scope>application</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>RequestBean1</managed-bean-name> <managed-bean-class>reqtracker.RequestBean1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Page1</managed-bean-name> <managed-bean-class>reqtracker.Page1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>TitleFrag</managed-bean-name> <managed-bean-class>reqtracker.TitleFrag</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> 90 <managed-bean> <managed-bean-name>MasterFrag</managed-bean-name> <managed-bean-class>reqtracker.MasterFrag</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>MainPage</managed-bean-name> <managed-bean-class>reqtracker.MainPage</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/Page1.jsp</from-view-id> <navigation-case> <from-outcome>mainPage</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> </navigation-rule> <!-- Title section navigation rules template begin --> <navigation-rule> <from-view-id>/MainPage.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> 91 </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> </navigation-rule> <!-- Title section navigation rules template end --> <navigation-rule> <from-view-id>/FunctionalReq.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> 92 <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>reqDetailPg</from-outcome> <to-view-id>/ReqDetail.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/QualityReq.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> 93 <navigation-case> <from-outcome>reqDetailPg</from-outcome> <to-view-id>/ReqDetail.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/Design.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> 94 <from-view-id>/Code.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/TestCase.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> 95 <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/ReqDetail.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> 96 <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/AdminTask.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> 97 <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPgCreate</from-outcome> <to-view-id>/AdminTaskCreate.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/AdminTaskCreate.jsp</from-view-id> <navigation-case> <from-outcome>page1</from-outcome> <to-view-id>/Page1.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>fnReq</from-outcome> <to-view-id>/FunctionalReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>qualityReq</from-outcome> <to-view-id>/QualityReq.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>designPg</from-outcome> <to-view-id>/Design.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>codePg</from-outcome> <to-view-id>/Code.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>testPg</from-outcome> <to-view-id>/TestCase.jsp</to-view-id> 98 </navigation-case> <navigation-case> <from-outcome>mainPg</from-outcome> <to-view-id>/MainPage.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPg</from-outcome> <to-view-id>/AdminTask.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPgCreate</from-outcome> <to-view-id>/AdminTaskCreate.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>FunctionalReq</managed-bean-name> <managed-bean-class>reqtracker.FunctionalReq</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>QualityReq</managed-bean-name> <managed-bean-class>reqtracker.QualityReq</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Design</managed-bean-name> <managed-bean-class>reqtracker.Design</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Code</managed-bean-name> <managed-bean-class>reqtracker.Code</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>TestCase</managed-bean-name> <managed-bean-class>reqtracker.TestCase</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>AdminTask</managed-bean-name> <managed-bean-class>reqtracker.AdminTask</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>AdminTaskCreate</managed-bean-name> 99 <managed-bean-class>reqtracker.AdminTaskCreate</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>ReqDetail</managed-bean-name> <managed-bean-class>reqtracker.ReqDetail</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> </faces-config> ProjectReportByID.jrxml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD JasperReport//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"> <jasperReport name="ProjectReportById" pageWidth="595" pageHeight="842" columnWidth="535" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20"> <style name="Arial_Normal" isDefault="true" fontName="Arial" fontSize="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/> <style name="Arial_Bold" fontName="Arial" isDefault="false" isBold="true" pdfFontName="Helvetica-Bold"/> <style name="Arial_Header1" fontName="Arial" isDefault="false" fontSize="22" isBold="true" pdfFontName="Helvetica-Bold"/> <style name="Arial_Bold_White" fontName="Arial" forecolor="white" isDefault="false" fontSize="12" isBold="true" pdfFontName="Helvetica-Bold"/> <queryString language="SQL"> <![CDATA[SELECT fnreq.`fnreq_num` AS fnreq_fnreq_num, fnreq.`fnreq_name` AS fnreq_fnreq_name, fnreq.`fnreq_priority` AS fnreq_fnreq_priority, fnreq.`fnreq_status` AS fnreq_fnreq_status, fnreq.`fnreq_definition` AS fnreq_fnreq_definition, fnreq.`fnreq_author` AS fnreq_fnreq_author, fnreq.`action_needed` AS fnreq_action_needed, fnreq.`req_type` AS fnreq_req_type, fnreq.`creation_date` AS fnreq_creation_date FROM `fnreq` fnreq]]> </queryString> <field name="req_type" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <field name="fnreq_num" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> 100 </field> <field name="action_needed" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <field name="fnreq_name" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <field name="fnreq_priority" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <field name="fnreq_status" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <field name="fnreq_definition" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <field name="fnreq_author" class="java.lang.String"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <field name="creation_date" class="java.sql.Date"> <fieldDescription><![CDATA[]]></fieldDescription> </field> <group name="req_type"> <groupExpression><![CDATA[$F{req_type}]]></groupExpression> <groupHeader> <band height="27" > <staticText> <reportElement mode="Opaque" x="0" y="0" width="139" height="27" forecolor="#FFFFFF" backcolor="#000000"/> <textElement> <font size="18"/> </textElement> <text><![CDATA[Req Type:]]></text> </staticText> <textField> <reportElement mode="Opaque" x="139" y="0" width="416" height="27" forecolor="#FFFFFF" backcolor="#000000"/> <textElement> <font size="18" isBold="true"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{req_type}]]></textFieldExpression> </textField> </band> </groupHeader> <groupFooter> <band height="8" > <line direction="BottomUp"> <reportElement key="line" x="1" y="4" width="554" height="1"/> </line> </band> 101 </groupFooter> </group> <group name="fnreq_num"> <groupExpression><![CDATA[$F{fnreq_num}]]></groupExpression> <groupHeader> <band height="28" > <staticText> <reportElement mode="Opaque" x="0" y="0" width="139" height="27" backcolor="#CCCCFF"/> <textElement> <font size="18"/> </textElement> <text><![CDATA[Number:]]></text> </staticText> <textField> <reportElement mode="Opaque" x="139" y="0" width="416" height="27" backcolor="#CCCCFF"/> <textElement> <font size="18"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{fnreq_num}]]></textFieldExpression> </textField> <line> <reportElement positionType="FixRelativeToBottom" x="0" y="27" width="555" height="1"/> </line> </band> </groupHeader> <groupFooter> <band height="8" > <line direction="BottomUp"> <reportElement key="line" x="1" y="4" width="554" height="1"/> </line> </band> </groupFooter> </group> <background> <band /> </background> <title> <band height="58" > <line> <reportElement x="0" y="8" width="555" height="1"/> </line> <line> <reportElement positionType="FixRelativeToBottom" x="0" y="51" width="555" height="1"/> </line> <staticText> <reportElement x="65" y="13" width="424" height="35"/> 102 <textElement textAlignment="Center"> <font size="26" isBold="true"/> </textElement> <text><![CDATA[Project Report]]></text> </staticText> </band> </title> <pageHeader> <band /> </pageHeader> <columnHeader> <band /> </columnHeader> <detail> <band height="200" > <staticText> <reportElement x="0" y="0" width="139" height="20"/> <textElement> <font size="12"/> </textElement> <text><![CDATA[Action Needed:]]></text> </staticText> <textField> <reportElement x="139" y="0" width="416" height="20"/> <textElement> <font size="12"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{action_needed}]]></textFieldExpression> </textField> <staticText> <reportElement x="0" y="20" width="139" height="20"/> <textElement> <font size="12"/> </textElement> <text><![CDATA[Name:]]></text> </staticText> <textField> <reportElement x="139" y="20" width="416" height="20"/> <textElement> <font size="12"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{fnreq_name}]]></textFieldExpression> </textField> <staticText> <reportElement x="0" y="40" width="139" height="20"/> <textElement> <font size="12"/> </textElement> <text><![CDATA[Priority:]]></text> </staticText> 103 <textField> <reportElement x="139" y="40" width="416" height="20"/> <textElement> <font size="12"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{fnreq_priority}]]></textFieldExpression> </textField> <staticText> <reportElement x="0" y="60" width="139" height="20"/> <textElement> <font size="12"/> </textElement> <text><![CDATA[Status:]]></text> </staticText> <textField> <reportElement x="139" y="60" width="416" height="20"/> <textElement> <font size="12"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{fnreq_status}]]></textFieldExpression> </textField> <staticText> <reportElement x="0" y="80" width="139" height="60"/> <textElement> <font size="12"/> </textElement> <text><![CDATA[Definition:]]></text> </staticText> <textField> <reportElement x="139" y="80" width="416" height="60"/> <textElement> <font size="12"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{fnreq_definition}]]></textFieldExpression> </textField> <staticText> <reportElement x="0" y="140" width="139" height="20"/> <textElement> <font size="12"/> </textElement> <text><![CDATA[Author:]]></text> </staticText> <textField> <reportElement x="139" y="140" width="416" height="20"/> <textElement> <font size="12"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA[$F{fnreq_author}]]></textFieldExpression> 104 </textField> <staticText> <reportElement x="0" y="160" width="139" height="20"/> <textElement> <font size="12"/> </textElement> <text><![CDATA[Date Modified:]]></text> </staticText> <textField> <reportElement x="139" y="160" width="416" height="20"/> <textElement> <font size="12"/> </textElement> <textFieldExpression class="java.util.Date"><![CDATA[$F{creation_date}]]></textFieldExpression> </textField> </band> </detail> <columnFooter> <band /> </columnFooter> <pageFooter> <band height="26" > <textField evaluationTime="Report" pattern="" isBlankWhenNull="false"> <reportElement key="textField" x="516" y="6" width="36" height="19" forecolor="#000000" backcolor="#FFFFFF"/> <box> <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> </box> <textElement> <font size="10"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA["" + $V{PAGE_NUMBER}]]></textFieldExpression> </textField> <textField pattern="" isBlankWhenNull="false"> <reportElement key="textField" x="342" y="6" width="170" height="19" forecolor="#000000" backcolor="#FFFFFF"/> <box> <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> 105 <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> </box> <textElement textAlignment="Right"> <font size="10"/> </textElement> <textFieldExpression class="java.lang.String"><![CDATA["Page " + $V{PAGE_NUMBER} + " of "]]></textFieldExpression> </textField> <textField pattern="" isBlankWhenNull="false"> <reportElement key="textField" x="1" y="6" width="209" height="19" forecolor="#000000" backcolor="#FFFFFF"/> <box> <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/> </box> <textElement> <font size="10"/> </textElement> <textFieldExpression class="java.util.Date"><![CDATA[new Date()]]></textFieldExpression> </textField> </band> </pageFooter> <summary> <band /> </summary> </jasperReport> 106 REFERENCES [1] Albin, Joseph. Creating and configuring a MySQL DataSource in GlassFish Application Server. [Online] Available: http://www.albeesonline.com/blog/2008/08/06/creating-and- configuring-a-mysql-datasource-in-glassfish-application-server/ [2] Apache Commons. Commons fileUpload. [Online] Available: http://commons.apache.org/fileupload/using.html [3] August, Susan, Requirements Analyst, IBM, Software Group. Ending requirements chaos. [Online] Available: http://www.ibm.com/developerworks/rational/library/2865.html [4] Bass, Len; Clement, Paul; Kazman, Rick; Software Architecture in Practice, 2nd Edition, Addison Wesley, 2003. [5] Compuware. OptimalTrace. Quality Solutions at Compuware. [Online] Available: http://www.compuware.com/quality.htm [6] Ferdinandi, Pat. (2000, June). Requirement Patterns – A Groundbreaking Approach. Strategic Business Decisions, Inc. [Online] Available: http://www.sbdi-consulting.com/PLFUMLRP.pdf [7] Fowler, Martin; Scott, Kendall. UML Distilled: A Brief Guide to the Standard Object Modeling Language (2nd Edition). [8] Goda Software. CASE Spec. Specify, Analyze, Verify and Validate your Systems. [Online] Available: http://www.analysttool.com/products.htm [9] JasperForge.org. JasperReports. [Online] Available: http://jasperforge.org/website/jasperreportswebsite/trunk/samples.html?group_id=252 [10] Pressman, Roger S. Software Engineering: A Practitioner’s Approach. New York, NY: McGraw Hill, 2005. [11] Rubinstein, David. (2007, March). Standish Group Report: There’s Less Development Chaos Today. [Online] Available: http://www.sdtimes.com/content/article.aspx?ArticleID=30247 107 [12] Smith, Aron, Paul SP. Open Source Requirements Management Tool. Source Forge. [Online] Available: http://sourceforge.net/projects/osrmt/ [13] Sun Microsystems. JavaServer Pages Technology Documentation. [Online] Available: http://java.sun.com/products/jsp/docs.html [14] Sun Microsystems. NetBeans Support Weblog. [Online] Available: http://blogs.sun.com/NetBeansSupport/entry/useful_resources_for_visual_web [15] Tran, Quan; Chung, Lawrence. NFR-Assistant: Tool Support for Achieving Quality. School of Computer Science, University of Texas at Dallas. [16] Woodstock Project, java.net. Glassfish – Project Wookstock Documentation. [Online] Available: https://woodstock.dev.java.net/Documentation.htm [17] Workspace.com. Lighthouse. A web-based requirements management tool. [Online] Available: http://www.workspace.com/ [18] Yeary, John. Java Evangelist John Yeary’s Blog. [Online] Available: http://javaevangelist.blogspot.com/2008/03/netbeans-visual-jsf-calendar-and-date.html