This document provides an overview and details of a forms application developed using the Spring Framework. It describes setting up the Spring Tool Suite environment, configuring dependencies and files, developing models, repositories, services and controllers to manage users, forms, questions and answers. It also covers implementing security and setting up the database schema and package structure. Views for login, registration, and managing forms, questions and answers are discussed.
Oracle General Ledger is a comprehensive financial management solution that enables recording and reviewing of accounting information. It allows importing data from other systems or direct journal entry. Key functions include the general accounting cycle, a global accounting engine, and support for multiple accounting methods and reporting currencies. Financial reports can be generated to aid decision making.
110906 ps-ritc-skills australia interim report resources industryRITCWA
This document provides a summary of Skills Australia's 2011 interim report on resources sector skill needs. The report finds that demand for skills in the resources sector is likely to be stronger than previously estimated due to more major projects being confirmed and higher commodity production forecasts. While the national labour market is tightening, further policy responses may be needed to ensure industry skill needs are met without impacting other sectors of the economy. These could include measures to increase labour force participation, mobility, and engagement of groups underrepresented in resources such as women and Indigenous Australians.
This document provides instructions for setting up the inventory organization structure for Oracle Application R12. It includes steps for defining a primary ledger and operating unit, custom inventory responsibility, security profile, workday calendar, item master organization, locations, subinventories, and other foundational elements. The goal is to establish the necessary setup for Inbox Business Technologies to use Oracle Inventory functionality.
SDLC stands for Software Development Life Cycle and refers to the process of planning, developing, testing and deploying an information system. It typically involves several stages including requirements analysis, design, development, testing, implementation and maintenance. There are various SDLC models like waterfall, iterative, spiral and V-model that define different approaches for how the development should proceed through each stage. The tutorial provides an overview of these common SDLC models and their characteristics.
This document provides an overview of Oracle Receivables functionality including setting up parties, transactions, processing invoices, payments, and adjustments. It discusses key areas like defining setup options, entering transactions, completing invoices, correcting errors, applying receipts, processing commitments, and remitting customer payments. The overview explains the various transaction types, accounting rules, payment methods, and status updates available within Oracle Receivables.
Android based crime managements syetem final year pdfBeresa Abebe
This document provides an introduction and overview of an Android-based Crime Management System project. It discusses the background and problems with the current (manual) system, and outlines the objectives, scope, methodology and significance of developing a new computerized system. The new system aims to store and provide crime information, reduce evidence gathering delays, minimize investigation time, and generate automated reports. It will allow police to access data via Android mobiles. The document describes the data collection and analysis methods, as well as the tools that will be used such as Android Studio, JDK and UML modeling.
The document provides information about Hafiz Abdul Rehman's internship at Zealcon Engineering (Pvt.) Ltd, including:
1) Zealcon works on projects like the UCH-II Gas Development Project and provides engineering services.
2) During his internship, Hafiz worked in the piping and dehydration unit departments to learn about piping systems and the amine process.
3) The dehydration unit uses glycol to remove water from natural gas through absorption and regeneration processes.
This document provides guidance for users of the Oracle HRMS system at Fujairah Chamber of Commerce. It begins with an introduction and then covers starting Oracle applications including logging on, choosing a responsibility, and navigating. It also provides guidance on getting help and exiting the application. The main sections include guidance on core HR functionality, recruitment functionality, defining work structures, and the system administrator responsibilities.
Oracle General Ledger is a comprehensive financial management solution that enables recording and reviewing of accounting information. It allows importing data from other systems or direct journal entry. Key functions include the general accounting cycle, a global accounting engine, and support for multiple accounting methods and reporting currencies. Financial reports can be generated to aid decision making.
110906 ps-ritc-skills australia interim report resources industryRITCWA
This document provides a summary of Skills Australia's 2011 interim report on resources sector skill needs. The report finds that demand for skills in the resources sector is likely to be stronger than previously estimated due to more major projects being confirmed and higher commodity production forecasts. While the national labour market is tightening, further policy responses may be needed to ensure industry skill needs are met without impacting other sectors of the economy. These could include measures to increase labour force participation, mobility, and engagement of groups underrepresented in resources such as women and Indigenous Australians.
This document provides instructions for setting up the inventory organization structure for Oracle Application R12. It includes steps for defining a primary ledger and operating unit, custom inventory responsibility, security profile, workday calendar, item master organization, locations, subinventories, and other foundational elements. The goal is to establish the necessary setup for Inbox Business Technologies to use Oracle Inventory functionality.
SDLC stands for Software Development Life Cycle and refers to the process of planning, developing, testing and deploying an information system. It typically involves several stages including requirements analysis, design, development, testing, implementation and maintenance. There are various SDLC models like waterfall, iterative, spiral and V-model that define different approaches for how the development should proceed through each stage. The tutorial provides an overview of these common SDLC models and their characteristics.
This document provides an overview of Oracle Receivables functionality including setting up parties, transactions, processing invoices, payments, and adjustments. It discusses key areas like defining setup options, entering transactions, completing invoices, correcting errors, applying receipts, processing commitments, and remitting customer payments. The overview explains the various transaction types, accounting rules, payment methods, and status updates available within Oracle Receivables.
Android based crime managements syetem final year pdfBeresa Abebe
This document provides an introduction and overview of an Android-based Crime Management System project. It discusses the background and problems with the current (manual) system, and outlines the objectives, scope, methodology and significance of developing a new computerized system. The new system aims to store and provide crime information, reduce evidence gathering delays, minimize investigation time, and generate automated reports. It will allow police to access data via Android mobiles. The document describes the data collection and analysis methods, as well as the tools that will be used such as Android Studio, JDK and UML modeling.
The document provides information about Hafiz Abdul Rehman's internship at Zealcon Engineering (Pvt.) Ltd, including:
1) Zealcon works on projects like the UCH-II Gas Development Project and provides engineering services.
2) During his internship, Hafiz worked in the piping and dehydration unit departments to learn about piping systems and the amine process.
3) The dehydration unit uses glycol to remove water from natural gas through absorption and regeneration processes.
This document provides guidance for users of the Oracle HRMS system at Fujairah Chamber of Commerce. It begins with an introduction and then covers starting Oracle applications including logging on, choosing a responsibility, and navigating. It also provides guidance on getting help and exiting the application. The main sections include guidance on core HR functionality, recruitment functionality, defining work structures, and the system administrator responsibilities.
Android based crime manage system industrial project iBeresa Abebe
This document describes plans for an Android-based crime management system project. The current manual system has weaknesses like a lack of technology, transportation, and ability to gather crime information quickly. The project aims to develop a computerized system to address these issues. It will allow police to enter criminal data, send reports automatically, and generate crime reports. The system is intended to improve crime handling and make information more accessible to the community and police. It will be developed using an object-oriented approach and UML modeling.
Android based crime manage system industrial project iBeresa Abebe
This document describes an Android-based crime management system project for Wollega University fourth year computer science students. The project aims to develop a mobile application to help address issues with the current paper-based crime tracking system. Some key points:
- The current system uses paper forms which has limitations like loss of forms, difficulty in retrieving and analyzing data.
- The new mobile app will allow police to digitally enter crime data like complaints, criminal details, and feedback. It will also generate reports for analysis.
- The app will have different functions for police officers, administrators, and general users. Data will be stored in a backend database.
- The project will use modeling techniques like use case diagrams
The document provides an overview of Oracle Business Intelligence Foundation Suite. It discusses the key components, including Oracle BI Server, Common Enterprise Information Model, Oracle Essbase, Oracle BI Publisher, and end-user capabilities like dashboards, reporting, and search. The suite offers an integrated platform for business intelligence, with unified access to enterprise data, a common semantic model, and self-service analytics.
Dassault Aviation is a French aircraft manufacturer founded in 1929. It is best known for business jets and military aircraft. The company has major facilities in France and subsidiaries worldwide. It employs over 11,000 people. Dassault designs and manufactures business jets under the Falcon brand and military aircraft including the Mirage and Rafale fighter jets. The company has expanded into unmanned aerial systems and space technology in recent years. It aims to develop new aircraft models and expand its international footprint.
The document provides setup instructions for Oracle Accounts Payable application version 12.1.3. It includes 28 setup steps to define configuration items like the accounting flexfield, payment terms, approval codes, payment programs, and payment formats. The setup is to be completed to implement the application for a company using accrual accounting.
Oracle HCM and Taleo Enterprise Fusion-Taleo Integration Configuration Guide...Feras Ahmad
The document provides guidance on configuring Oracle Taleo for integration with Oracle Fusion HCM. It describes setting up key Taleo elements like organizations, locations, job fields, and statuses to match the structure in Fusion HCM. It also covers initial data export from Fusion to populate Taleo, and configuring the ongoing synchronization process between the two systems. The document is a step-by-step guide for customers integrating Taleo recruiting with Fusion HCM using the out-of-the-box integration.
This document provides a training guide for using the Oracle EBS R12 Human Resources system. It covers topics such as starting Oracle applications, choosing a responsibility, navigating forms, getting help, and the core HR functionality including entering employee data, recruitment, defining work structures, and administration settings. The guide is intended to help FUJCCI HR staff learn the essential functionality of Oracle HRMS. It provides step-by-step instructions on common HR tasks in Oracle such as hiring, promotions, payroll, and system configuration.
Candy - Construction Estimating & Valuations - rev 2.01Jerico Awat
This document provides a table of contents for a course on construction estimating and valuations. The document outlines 12 chapters that will be covered in the course, including importing a bill of quantities, pricing bill items, using subcontractors, adding markups, and post-tender control. Key topics that will be addressed include downloading software, setting up new projects, importing Excel spreadsheets, defining trades, using worksheets to price items, analyzing resources, and using masters for pricing.
This document provides an introduction and hands-on guide to using Windows PowerShell with SharePoint 2013, Office 365, and Active Directory. It discusses getting started with PowerShell basics, commands, writing cmdlets, using variables and objects, filtering outputs, and interacting with PowerShell. It also covers adding the SharePoint snap-in, managing permissions, searching/working with SharePoint objects, provisioning service applications, and creating warm-up scripts. The document aims to help developers get started writing PowerShell scripts for SharePoint administration and management.
This document provides an overview of the Candy Construction Estimating and Valuations user interface and navigation. It describes the main sections of the user interface including the title bar, application tabs, menus and toolbars. It also explains how to navigate between documents and use various keyboard shortcuts and right-click menu functions. The document concludes with information on customizing system fonts, colors, toolbars and configuring folder paths.
This document provides an index and overview of the chapters contained in the Candy Construction Planning & Programming course notes. The chapters cover topics like starting a new company and job in Candy, using the planning and calendar modules, creating and customizing bar charts to plan activities, program analysis using checklists and timelines, reporting on resources, procurement scheduling, and updating progress. The course aims to teach the objectives and logic of Candy planning as well as practical techniques for filtering, sorting, copying and navigating documents.
The document provides instructions on using various features in Oracle HRMS, including starting the application, logging in, navigating forms, entering employee data, and defining organizational structures. It covers topics such as choosing responsibilities, opening forms from the navigator, using the toolbar, getting help, and exiting the application. The document is meant as a simple guide for HR staff to facilitate key functionality in Oracle HRMS.
Hsa programmers reference manual (version 1.0 provisional)HSA Foundation
This document provides a programmer's reference manual for HSAIL, which is a virtual instruction set architecture and intermediate language for heterogeneous computing. It describes the HSAIL programming model, including grids, work-groups, and work-items. It also covers memory types, wavefronts, and programming for scalable data-parallel applications. The document is intended for developers implementing the HSA architecture.
This document provides an overview of SQL concepts and Oracle Applications. It includes classifications of SQL commands like tables, views, sequences and explain plans. It also covers PL/SQL concepts such as block structure, cursors, exceptions, procedures, functions, packages and triggers. The document discusses Oracle Applications, ERP methodology, database structure, file architecture and entering data into Oracle Applications.
This document provides an overview of biomechanics and its applications. It discusses the importance of understanding biomechanics for analyzing human movement, improving performance and preventing injuries. Specific topics covered include the anatomy of the spine, biomechanics of safe lifting, seating design, manual material handling, hand tool design, musculoskeletal disorders, and measurement of human vibration. The objective is to define key biomechanics concepts and analyze their role in safety assessments and ergonomic evaluations.
El documento describe las estructuras clínicas o repetitivas en programación, específicamente los problemas repetitivos o cíclicos que requieren ejecutar un conjunto de acciones una cantidad específica de veces, ya sea una cantidad fija o variable. Explica que los ciclos con un número determinado de iteraciones son aquellos donde el número de iteraciones se conoce antes de ejecutar el ciclo.
El documento proporciona 10 pasos para editar una foto en capas: 1) abrir una imagen, 2) usar F7 para ver las capas, 3) usar la herramienta de polígono liso y establecer el valor de suavizado en 4, 4) seleccionar el cabello, 5) copiar y pegar para crear una nueva capa, 6) arrastrar la nueva capa por encima del icono de capa nueva, 7) ajustar el color verde de la primera capa, 8) ajustar el color magenta del cabello en la
Android based crime manage system industrial project iBeresa Abebe
This document describes plans for an Android-based crime management system project. The current manual system has weaknesses like a lack of technology, transportation, and ability to gather crime information quickly. The project aims to develop a computerized system to address these issues. It will allow police to enter criminal data, send reports automatically, and generate crime reports. The system is intended to improve crime handling and make information more accessible to the community and police. It will be developed using an object-oriented approach and UML modeling.
Android based crime manage system industrial project iBeresa Abebe
This document describes an Android-based crime management system project for Wollega University fourth year computer science students. The project aims to develop a mobile application to help address issues with the current paper-based crime tracking system. Some key points:
- The current system uses paper forms which has limitations like loss of forms, difficulty in retrieving and analyzing data.
- The new mobile app will allow police to digitally enter crime data like complaints, criminal details, and feedback. It will also generate reports for analysis.
- The app will have different functions for police officers, administrators, and general users. Data will be stored in a backend database.
- The project will use modeling techniques like use case diagrams
The document provides an overview of Oracle Business Intelligence Foundation Suite. It discusses the key components, including Oracle BI Server, Common Enterprise Information Model, Oracle Essbase, Oracle BI Publisher, and end-user capabilities like dashboards, reporting, and search. The suite offers an integrated platform for business intelligence, with unified access to enterprise data, a common semantic model, and self-service analytics.
Dassault Aviation is a French aircraft manufacturer founded in 1929. It is best known for business jets and military aircraft. The company has major facilities in France and subsidiaries worldwide. It employs over 11,000 people. Dassault designs and manufactures business jets under the Falcon brand and military aircraft including the Mirage and Rafale fighter jets. The company has expanded into unmanned aerial systems and space technology in recent years. It aims to develop new aircraft models and expand its international footprint.
The document provides setup instructions for Oracle Accounts Payable application version 12.1.3. It includes 28 setup steps to define configuration items like the accounting flexfield, payment terms, approval codes, payment programs, and payment formats. The setup is to be completed to implement the application for a company using accrual accounting.
Oracle HCM and Taleo Enterprise Fusion-Taleo Integration Configuration Guide...Feras Ahmad
The document provides guidance on configuring Oracle Taleo for integration with Oracle Fusion HCM. It describes setting up key Taleo elements like organizations, locations, job fields, and statuses to match the structure in Fusion HCM. It also covers initial data export from Fusion to populate Taleo, and configuring the ongoing synchronization process between the two systems. The document is a step-by-step guide for customers integrating Taleo recruiting with Fusion HCM using the out-of-the-box integration.
This document provides a training guide for using the Oracle EBS R12 Human Resources system. It covers topics such as starting Oracle applications, choosing a responsibility, navigating forms, getting help, and the core HR functionality including entering employee data, recruitment, defining work structures, and administration settings. The guide is intended to help FUJCCI HR staff learn the essential functionality of Oracle HRMS. It provides step-by-step instructions on common HR tasks in Oracle such as hiring, promotions, payroll, and system configuration.
Candy - Construction Estimating & Valuations - rev 2.01Jerico Awat
This document provides a table of contents for a course on construction estimating and valuations. The document outlines 12 chapters that will be covered in the course, including importing a bill of quantities, pricing bill items, using subcontractors, adding markups, and post-tender control. Key topics that will be addressed include downloading software, setting up new projects, importing Excel spreadsheets, defining trades, using worksheets to price items, analyzing resources, and using masters for pricing.
This document provides an introduction and hands-on guide to using Windows PowerShell with SharePoint 2013, Office 365, and Active Directory. It discusses getting started with PowerShell basics, commands, writing cmdlets, using variables and objects, filtering outputs, and interacting with PowerShell. It also covers adding the SharePoint snap-in, managing permissions, searching/working with SharePoint objects, provisioning service applications, and creating warm-up scripts. The document aims to help developers get started writing PowerShell scripts for SharePoint administration and management.
This document provides an overview of the Candy Construction Estimating and Valuations user interface and navigation. It describes the main sections of the user interface including the title bar, application tabs, menus and toolbars. It also explains how to navigate between documents and use various keyboard shortcuts and right-click menu functions. The document concludes with information on customizing system fonts, colors, toolbars and configuring folder paths.
This document provides an index and overview of the chapters contained in the Candy Construction Planning & Programming course notes. The chapters cover topics like starting a new company and job in Candy, using the planning and calendar modules, creating and customizing bar charts to plan activities, program analysis using checklists and timelines, reporting on resources, procurement scheduling, and updating progress. The course aims to teach the objectives and logic of Candy planning as well as practical techniques for filtering, sorting, copying and navigating documents.
The document provides instructions on using various features in Oracle HRMS, including starting the application, logging in, navigating forms, entering employee data, and defining organizational structures. It covers topics such as choosing responsibilities, opening forms from the navigator, using the toolbar, getting help, and exiting the application. The document is meant as a simple guide for HR staff to facilitate key functionality in Oracle HRMS.
Hsa programmers reference manual (version 1.0 provisional)HSA Foundation
This document provides a programmer's reference manual for HSAIL, which is a virtual instruction set architecture and intermediate language for heterogeneous computing. It describes the HSAIL programming model, including grids, work-groups, and work-items. It also covers memory types, wavefronts, and programming for scalable data-parallel applications. The document is intended for developers implementing the HSA architecture.
This document provides an overview of SQL concepts and Oracle Applications. It includes classifications of SQL commands like tables, views, sequences and explain plans. It also covers PL/SQL concepts such as block structure, cursors, exceptions, procedures, functions, packages and triggers. The document discusses Oracle Applications, ERP methodology, database structure, file architecture and entering data into Oracle Applications.
This document provides an overview of biomechanics and its applications. It discusses the importance of understanding biomechanics for analyzing human movement, improving performance and preventing injuries. Specific topics covered include the anatomy of the spine, biomechanics of safe lifting, seating design, manual material handling, hand tool design, musculoskeletal disorders, and measurement of human vibration. The objective is to define key biomechanics concepts and analyze their role in safety assessments and ergonomic evaluations.
El documento describe las estructuras clínicas o repetitivas en programación, específicamente los problemas repetitivos o cíclicos que requieren ejecutar un conjunto de acciones una cantidad específica de veces, ya sea una cantidad fija o variable. Explica que los ciclos con un número determinado de iteraciones son aquellos donde el número de iteraciones se conoce antes de ejecutar el ciclo.
El documento proporciona 10 pasos para editar una foto en capas: 1) abrir una imagen, 2) usar F7 para ver las capas, 3) usar la herramienta de polígono liso y establecer el valor de suavizado en 4, 4) seleccionar el cabello, 5) copiar y pegar para crear una nueva capa, 6) arrastrar la nueva capa por encima del icono de capa nueva, 7) ajustar el color verde de la primera capa, 8) ajustar el color magenta del cabello en la
This document provides a summary of best practices for developing and deploying secure web applications. It outlines a hierarchical view of application security with three levels - single transactions, session security, and full application security. Guidelines are presented for each level to help developers implement authentication, authorization, input validation, error handling and more to protect applications and user data.
This document provides an introduction to business modeling concepts and a comparison of the Unified Modeling Language (UML) and the Integration DEFinition (IDEF) family of languages for business modeling. It defines key terms like business models and processes. It also discusses how business models can provide requirements for information systems and support business improvement vs innovation. The document outlines some important business concepts and the relationship between business and software architecture.
This document provides an overview of the project plan for developing an online hotel room booking system. It discusses the scope, objectives, and problems with the current manual system. It then describes the proposed computerized solution and outlines the tasks involved in project planning and control, including quality assurance plans, documentation standards, programming standards, and project management. It also discusses scheduling, risk management, requirements analysis, process and data modeling, testing approaches, and references. The overall aim is to develop a system that can efficiently manage all hotel activities and operations.
This document provides a summary of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework 11g Release 2 (11.1.2.0.0). It is authored by Ralph Gordon and others at Oracle and covers topics related to building applications using Oracle ADF. The document includes information on Oracle ADF architecture, building applications with ADF, and the sample Fusion Order Demo application included with ADF.
This document provides instructions for installing and setting up the Hybrid Application Toolkit (HAT) on Windows. It outlines prerequisites like Java JDK 8, Android SDK 24.4.1 or higher, Apache Ant 1.9.6, Node.js 5.4.1, Git client. It then provides step-by-step guides for installing each prerequisite, configuring environment variables, and installing additional tools like the SAP Kapsel Plugin, Git, Node.js, Cordova and Plugman. The goal is to prepare a development environment for building and deploying hybrid mobile apps with HAT.
This document describes a project to interface an application with a master product database. It discusses functional and technical overviews of change requests, cancellation requests, approval/routing processes, and generating NOPC reports. It also covers testing plans and provides information on using AngularJS to develop a single page application for the NOPC report. Diagrams illustrate the technical processes and flowcharts depict the functional workflows. The project aims to integrate an application with a centralized product database to support change management.
This document provides reference documentation for Spring Data Key-Value (SDKV) version 1.0.0.M3. It explains the Redis and Riak support provided by SDKV, allowing for easy configuration and access to these key-value data stores from Spring applications. SDKV offers both low-level and high-level abstractions for interacting with Redis and Riak to simplify development and handle infrastructural concerns.
The document provides an overview of Application Builder and instructions for getting started using it. Application Builder is a tool for creating search applications without coding. It allows configuring facets, search results details, and content rendering. The document explains how Application Builder is preconfigured for clean MarkLogic installations and how it is handled during upgrades. It also provides instructions for starting Application Services and building a sample movies application using the tool's interface.
This document discusses principles for building application front-ends in a service-oriented world. It proposes a Service-Oriented Front-End Architecture (SOFEA) style with the following key principles: 1) Decouple the processes of application download, presentation flow, and data interchange; 2) Presentation flow should be driven by client-side components and managed within the client; 3) Data interchange between tiers should follow common standards to avoid integrity issues and support rich data. Adhering to these principles can help integrate presentation tiers with increasingly service-oriented backends.
This Business Improvement Proposal was created by WebIT2 Consultants (Sarah Killey, Donald Gee, Mark Cottman-fields, Darren Cann and Sean Marshall) for the Queensland University of Technology (QUT) Library.
The plan outlines an in-depth situational analysis, proposal description, recommended solution, key benefits, business drivers, return on investment and implementation plan.
This is an assessment piece for INB346 - Enterprise 2.0 unit, Semester 2, 2009 (Lecturer Dr Jason Watson).
This document provides a 3-sentence summary of the Oracle Manufacturing APIs and Open Interfaces Manual:
The manual describes the application programming interfaces (APIs) and open interfaces that allow external systems to integrate with Oracle Manufacturing. It covers topics such as bills of material, cost management, inventory, order management, master scheduling, and purchasing. The interfaces allow data to be exchanged in both directions to enable automated processes between different software applications.
The document is a book titled "Book of Vaadin: Vaadin 7 - 2nd Edition" that provides an introduction to Vaadin, a Java framework for building web user interfaces, and covers topics such as getting started, the architecture, building server-side applications, user interface components, managing layouts, themes, and binding components to data.
Enterprise applications are designed to solve problems for large organizations and are multi-tiered, with functionality separated into isolated tiers like a client tier, middle tier, and data tier. The Java EE platform reduces the complexity of developing these large-scale, multi-tiered applications by providing APIs and services for tasks like security, reliability, and scalability so developers can focus on functionality. Tiered applications improve performance, scalability, and maintainability compared to traditional monolithic applications.
This document describes the OpenACC API, which allows programmers to offload compute intensive regions of CPU code to attached accelerators like GPUs. It defines OpenACC directives, runtime routines, and environment variables. Directives are used to specify regions for offloading and augment compiler information. Runtime routines control device behavior and query properties. Environment variables also control device behavior.
This document discusses unit testing Web APIs using the NUnit and Moq frameworks. It provides an overview of unit testing and the NUnit and Moq frameworks. It then details setting up a test project and installing necessary packages. The document focuses on writing unit tests for the business logic layer and controllers, demonstrating how to test a ProductService class by mocking dependencies, writing test methods, and more.
This document provides an overview and reference guide for the Zend Framework 1.10.x. It covers key concepts like MVC architecture, autoloading, plugins, layouts, views, forms, sessions, authentication, authorization, searching and pagination. The guide includes tutorials on setting up a basic MVC application as well as using specific Zend Framework components.
This document provides guidance on implementing Lean Six Sigma process improvement projects within colleges. It discusses the DMAIC process structure that projects follow, including defining the project goals, measuring the current process, analyzing opportunities for improvement, implementing changes, and controlling the new process. The document also covers selecting projects and teams, running meetings, process mapping, presentations of results, and ensuring improvements are sustained. The overall aim is to provide a framework to help colleges identify and eliminate waste in processes to improve outcomes for students.
This document proposes developing an online insurance survey portal for Saleem Siddiqui and Co., an insurance surveying company. The portal will automate the company's records for different insurance policies like fire, motor, and marine insurance. It will allow inserting, updating, and deleting customer records and claims data. The system will have admin and user roles. It will be developed using .NET Framework in Visual Studio 2010 and tested over 4 months before delivery with the website and documentation. Hardware requirements include at least 10GB RAM, 500GB hard drive, and minimum 2.4GHz CPU.
This document announces a two-step Broad Agency Announcement (BAA) for the Air Force FY 2013 Rapid Innovation Fund (RIF) program. It provides information on program objectives, submission requirements and schedules, evaluation criteria, and anticipated funding. The goal is to fund innovative technologies that address critical Air Force needs outlined in an attachment, with up to 25 awards totaling $45-65 million expected. The first step requires submission of white papers by October 8, 2013. Invited offerors will then submit full proposals which will be evaluated starting in December 2013.
Similar to IndieLabs-FormsApp Using Spring Framework (20)
5. 1 | P a g e
1. Introduction
1.1. Application Overview
This tutorial will take you through learning how to develop a kind of simple Java EE
web application using Spring MVC. The idea of the application is very simple, we
have a collection of forms that contain two types of questions, written and multiple
choice. The admin can manage all of these, and the regular users can answer those
questions many times.
1.2. Outcomes
At the end of this tutorial, you should be able to achieve the following:
Setup the development environment.
Setup the XML configurations for dependencies, data source and Spring
Security.
Create models with the proper relationships mapped to the database.
Create services.
Create repositories.
Create controllers.
Create views.
1.3. Pre-requisites
1. Good knowledge of development using Java SE.
2. Basic knowledge of MVC pattern.
3. Basic knowledge of HTML.
1.4. Requirements
To follow along with the tutorial, you should have the following:
1. STS IDE installed. (In this tutorial, version 3.6.4 is used)
2. JDK 1.6 or 1.7. (version 1.8 results in problems in the version of STS used,
not sure about higher versions of STS)
3. MySQL 5 database. (In this tutorial, Wamp server is used for this purpose)
1.5. GitHub Repository
All the final files of the project exist on the GitHub repository on the following link:
https://github.com/abahhar/FormsApp
6. 2 | P a g e
2. STS Setup
First, we have to create a new Spring MVC project, you could create a new one and it
will create all the default files and directory structure we need.
To create a new Spring MVC Project, please do the following:
1. FileNewSpring Project.
2. Set the project name to FormsApp.
3. Choose Spring MVC Project.
4. Write the package name as: com.abahhar.formsApp.
5. Click finish.
The default Spring MVC project which is created contains a default HomeController
in the package “com.abahhar.formsapp” and a home.jsp webpage in the views folder.
This simple application shows you a hello world page with the current date and time.
To run the application, you could simply drag the application folder “FormsApp” to
the Pivotal tc server which exists in the window below the package explorer, and then
in the same window of the servers, you simply click the green arrow to run the
application.
2.1. STS Loading Main Class Bug
In the current version and the following one, there’s a bug in the IDE that results in
not running the application, you might encounter a statement in the output window
that says “Could not find or load main class”.
To solve the issue, please follow the first solution suggested in the following URL:
http://stackoverflow.com/questions/29004274/error-after-update-to-sts-3-6-4-release
7. 3 | P a g e
2.2. POM.xml Dependencies
To be able to use libraries in Spring Framework, we should handle the dependencies
ourselves in pom.xml file which exists in the root document of our application. This
section provides you with the needed dependencies to be added.
2.2.1. JPA Dependencies
4. <!-- JPA Dependencies -->
5. <dependency>
6. <groupId>org.springframework</groupId>
7. <artifactId>spring-core</artifactId>
8. <version>${org.springframework-version}</version>
9. </dependency>
10. <dependency>
11. <groupId>org.springframework.data</groupId>
12. <artifactId>spring-data-jpa</artifactId>
13. <version>1.2.0.RELEASE</version>
14. </dependency>
15. <dependency>
16. <groupId>org.springframework</groupId>
17. <artifactId>spring-orm</artifactId>
18. <version>${org.springframework-
version}</version>
19. </dependency>
20. <dependency>
21. <groupId>org.hibernate</groupId>
22. <artifactId>hibernate-
entitymanager</artifactId>
23. <version>4.1.7.Final</version>
24. </dependency>
2.2.2 Spring Security Dependencies
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<!-- Spring Security tag library to be used in the views
-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
9. 5 | P a g e
2.3. Servlet-Context.xml Configuration
This configuration file exist in the following directory:
FormsAppsrcmainwebappWEB-INFspringappServlet
Please make sure that it contains the following code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"
xmlns:security="http://www.springframework.org/schema/security">
<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently
serving up static resources in the ${webappRoot}/resources directory
-->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp
resources in the /WEB-INF/views directory -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResol
ver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<context:annotation-config/>
<context:component-scan base-package="com.abahhar.formsapp" />
<jpa:repositories base-package="com.abahhar.formsapp.repository"/>
<tx:annotation-driven/>
</beans>
10. 6 | P a g e
Please notice this fragment of code:
<context:annotation-config/>
<context:component-scan base-package="com.abahhar.formsapp" />
<jpa:repositories base-package="com.abahhar.formsapp.repository"/>
<tx:annotation-driven/>
What this fragment does is that it scans for the Spring components and repositories in
the specified packages. Components can be controllers or services.
This scan is done automatically by Spring Framework in order to inject the
components and repositories later in the code, this is the dependency injection feature
supported in Spring Framework, later in the code when we want to inject a service or
repository, we will need to annotate it with @Autowired, and Spring Framework will
do the job of injecting the right dependency since it scans in the proper packages we
specified in this configuration.
Furthermore, notice the prefix and the suffix values specified by the default Spring
MVC Project, these values will be used to enable the ViewResolver to find the view
that we want. For example, in the controller we could return a string of a view as
“/forms/create”, this string will be evaluated as “WEB-INF/views/forms/create.jsp”.
As you notice, the prefix is added to the beginning of the returned string and the
suffix is added to the end of it.
11. 7 | P a g e
2.4. Datasource.xml Configuration
Here we setup the configuration for the database connection, please be sure to include
the configuration file datasource.xml in the package “src/main/resources”, and include
the following fragment of code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost/helloWorld"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactory
Bean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan"
value="com.abahhar.formsapp.domain" />
<property name="persistenceProviderClass"
value="org.hibernate.ejb.HibernatePersistence" />
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoa
dTimeWeaver" />
</property>
<property name="jpaProperties">
<props>
<prop
key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"
/>
</bean>
</beans>
For your settings, put the correct link for the local server hosting the database and its
port if not 80, and the name of the database after the slash “/”, and the correct
username and password. In this tutorial, the name of the database is helloWorld.
12. 8 | P a g e
2.5. Spring-Security.xml Configuration
Here we setup the configuration for Spring Security. Spring Security is a ready library
that is used for authentication and authorization of users. Using the following library,
we can have a login system and every user could have roles which with he can be
authorized to the different parts of the application.
Please be sure to include the configuration file spring-security.xml in the package
“src/main/resources”, and include the following fragment of code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-
3.1.xsd"
xmlns:security="http://www.springframework.org/schema/security">
<context:annotation-config />
<context:component-scan base-package="com.abahhar.formsapp.service"
/>
<jpa:repositories base-package="com.abahhar.formsapp.repository"/>
<!-- Spring Security Configuration -->
<security:http pattern="/resources/**" security="none"/> <!--
Permit access to static resources -->
<security:http auto-config='true' use-expressions="true"> <!-- use-
expressions enables using expressions like isAuthorized(),
isAnonymous() & isRole() -->
<security:intercept-url pattern="/user-login"
access="isAnonymous()"/> <!-- To avoid redirect loop since login-page
changed -->
<security:intercept-url pattern="/forms/**"
access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/simpleQuestions/**"
access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/mcQuestions/**"
access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/simpleAnswers/**"
access="hasRole('ROLE_USER')"/>
13. 9 | P a g e
<security:intercept-url pattern="/choiceAnswers/**"
access="hasRole('ROLE_USER')"/>
<security:form-login login-page="/user-login"
default-target-url="/forms"
always-use-default-target="true"
authentication-failure-url="/error-login" />
<security:logout logout-success-url="/forms" />
</security:http>
<!--
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="jimi" password="jimispassword"
authorities="ROLE_USER, ROLE_ADMIN" />
<security:user name="bob" password="bobspassword"
authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
-->
<security:authentication-manager>
<security:authentication-provider user-service-
ref="customUserDetailsService">
<security:password-encoder hash="sha" />
</security:authentication-provider>
</security:authentication-manager>
</beans>
It seems that this file contains a lot of things, but let’s decompose it and explain
what’s happening.
<context:annotation-config />
<context:component-scan base-package="com.abahhar.formsapp.service"
/>
<jpa:repositories base-package="com.abahhar.formsapp.repository"/>
We have seen this fragment of code in servlet-context.xml, but because of the
decomposition we are making, the Spring Security later will need to inject some
service dependencies for its library, and that won’t work unless we add the following
fragment of code in this file.
14. 10 | P a g e
<!-- Spring Security Configuration -->
<security:http pattern="/resources/**" security="none"/> <!--
Permit access to static resources -->
<security:http auto-config='true' use-expressions="true"> <!-- use-
expressions enables using expressions like isAuthorized(),
isAnonymous() & isRole() -->
<security:intercept-url pattern="/user-login"
access="isAnonymous()"/> <!-- To avoid redirect loop since login-page
changed -->
<security:intercept-url pattern="/forms/**"
access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/simpleQuestions/**"
access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/mcQuestions/**"
access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/simpleAnswers/**"
access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/choiceAnswers/**"
access="hasRole('ROLE_USER')"/>
<security:form-login login-page="/user-login"
default-target-url="/forms"
always-use-default-target="true"
authentication-failure-url="/error-login" />
<security:logout logout-success-url="/forms" />
</security:http>
Here we setup the authorization settings, meaning that which links are to be accessed
and which are denied for each role.
First we set the resources folder to be accessible by all, because there is where the
images, CSS and JavaScript files reside.
Second, we set to attributes in the second http tag, auto-config to true, and use-
expressions to true.
Auto-config will make the Spring Security insert default tags and attributes for setting
everything, because there are other things that we do not want to bother ourselves
with, so we let it set it to default values.
Use-expression attribute will enable us to use expressions like “isAnonymous()” and
“hasRole()” in the configuration file and the views later, to be able show the proper
features to proper users.
Intercept-url tag is used to set two things, the URL pattern and the role that is
authorized to access that URL pattern. You can set whatever URL to whatever role
you would like, taking into account that in this application we will have
ROLE_ADMIN and ROLE_USER.
Form-login tag sets the default URL for the login page, the default target URL which
to be directed to after login, the page to be directed to if the login fails and the page to
be directed to after the logout action.
15. 11 | P a g e
The last fragments to discuss are the authentication-manager tag, the commented one
could be used to have in-memory users set up by you as you like, which you could use
in running the application as they were to exist as registered users.
The second and used one, is setup to use the customized user service which we will
setup later, and have the hashing setup to be using sha encryption, you could use other
hashing settings such as “plaintext”, which deals with the password with no
encryption, and “md5”, which uses md5 encryption.
2.6. Web.xml Configuration
The last configuration file to modify is web.xml, which exists in the following
directory:
FormsAppsrcmainwebappWEB-INF
Please make sure that the file contains the following fragment of code:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all
Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml,
classpath:datasource.xml,
classpath:spring-security.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and
Filters -->
<listener>
<listener-
class>org.springframework.web.context.ContextLoaderListener</listener
-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-
context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
16. 12 | P a g e
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring Security Filters -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-
class>org.springframework.web.filter.DelegatingFilterProxy</filter-
class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Here we have to things added to the default file, the import of the datasource.xml and
spring-security.xml files in this fragment of code:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml,
classpath:datasource.xml,
classpath:spring-security.xml
</param-value>
</context-param>
And some settings for springSecurityFilterChain that must exist, so that Spring
Security to works:
<!-- Spring Security Filters -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-
class>org.springframework.web.filter.DelegatingFilterProxy</filter-
class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Please note in the first fragment of code, “classpath” evaluates to the directory
“src/main/resources”, which is the package stated that you should include the files in
when explaining setting the configuration files.
17. 13 | P a g e
2.7. Packages
In this tutorial, we setup the project to have the following packages:
1. Com.abahhar.formsapp
2. Com.abahhar.formsapp.controller
3. Com.abahhar.formsapp.domain
4. Com.abahhar.formsapp.repository
5. Com.abahhar.formsapp.service
6. Com.abahhar.formsapp.wrapper
2.8. Static Resources
Static resources such as images, CSS and JavaScript files should exist in the following
directory: “FormsAppsrcmainwebappresources”.
2.9. Class Diagram
This is the class diagram that the web application is based on:
18. 14 | P a g e
2.10. Database Schema
The following is the schema of the database tables that we will be using:
Roles
Role ID Role
Users
User ID Username Password
UsersRoles
User ID Role ID
Forms
Form ID Title
AnsweredForms
User ID Form ID
Questions
Question ID Text Form ID
19. 15 | P a g e
SimpleQuestions
Question ID NumberOfQuestions
MCQuestions
Question ID
Choices
Choice ID Text Question ID
AnsweredSimpleQuestion
SimpleAnswer ID Text Question ID User ID
AnsweredMCQuestion
MCAnswer ID Choice ID Question ID User ID
20. 16 | P a g e
In order to create the database tables in your database, please use the following SQL
statements:
--
-- Table structure for table `choiceanswers`
--
CREATE TABLE `choiceanswers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`choice_id` int(11) NOT NULL,
`question_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `choice_id` (`choice_id`),
KEY `question_id` (`question_id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
-- --------------------------------------------------------
--
-- Table structure for table `choices`
--
CREATE TABLE `choices` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(50) NOT NULL,
`question_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `question_id` (`question_id`),
KEY `question_id_2` (`question_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=78 ;
-- --------------------------------------------------------
--
-- Table structure for table `forms`
--
CREATE TABLE `forms` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
-- --------------------------------------------------------
--
-- Table structure for table `mcquestions`
--
CREATE TABLE `mcquestions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=47 ;
-- --------------------------------------------------------
--
-- Table structure for table `questions`
21. 17 | P a g e
--
CREATE TABLE `questions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(50) NOT NULL,
`form_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `form_id` (`form_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=47 ;
-- --------------------------------------------------------
--
-- Table structure for table `roles`
--
CREATE TABLE `roles` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`role` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
-- --------------------------------------------------------
--
-- Table structure for table `simpleanswers`
--
CREATE TABLE `simpleanswers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(50) NOT NULL,
`question_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `question_id` (`question_id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
-- --------------------------------------------------------
--
-- Table structure for table `simplequestions`
--
CREATE TABLE `simplequestions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=30 ;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE `users` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`login` varchar(20) NOT NULL,
`password` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;
22. 18 | P a g e
-- --------------------------------------------------------
--
-- Table structure for table `usersforms`
--
CREATE TABLE `usersforms` (
`user_id` int(11) NOT NULL,
`form_id` int(11) NOT NULL,
PRIMARY KEY (`user_id`,`form_id`),
KEY `form_id` (`form_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
-- --------------------------------------------------------
--
-- Table structure for table `user_roles`
--
CREATE TABLE `user_roles` (
`user_id` int(6) NOT NULL,
`role_id` int(6) NOT NULL,
KEY `user` (`user_id`),
KEY `role` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `choiceanswers`
--
ALTER TABLE `choiceanswers`
ADD CONSTRAINT `choiceanswers_ibfk_1` FOREIGN KEY (`choice_id`)
REFERENCES `choices` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `choiceanswers_ibfk_2` FOREIGN KEY (`question_id`)
REFERENCES `mcquestions` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `choiceanswers_ibfk_3` FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `choices`
--
ALTER TABLE `choices`
ADD CONSTRAINT `choices_ibfk_1` FOREIGN KEY (`question_id`)
REFERENCES `mcquestions` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `mcquestions`
--
ALTER TABLE `mcquestions`
ADD CONSTRAINT `mcquestions_ibfk_1` FOREIGN KEY (`id`) REFERENCES
`questions` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `questions`
--
ALTER TABLE `questions`
23. 19 | P a g e
ADD CONSTRAINT `questions_ibfk_1` FOREIGN KEY (`form_id`)
REFERENCES `forms` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `simpleanswers`
--
ALTER TABLE `simpleanswers`
ADD CONSTRAINT `simpleanswers_ibfk_1` FOREIGN KEY (`question_id`)
REFERENCES `simplequestions` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `simpleanswers_ibfk_2` FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `simplequestions`
--
ALTER TABLE `simplequestions`
ADD CONSTRAINT `simplequestions_ibfk_1` FOREIGN KEY (`id`)
REFERENCES `questions` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `usersforms`
--
ALTER TABLE `usersforms`
ADD CONSTRAINT `usersforms_ibfk_1` FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `usersforms_ibfk_2` FOREIGN KEY (`form_id`)
REFERENCES `forms` (`id`) ON DELETE CASCADE;
Also, use the following SQL statements to populate users, roles and user_roles tables:
INSERT INTO `users` (`id`, `login`, `password`) VALUES
(1, 'admin', '3d4f2bf07dc1be38b20cd6e46949a1071f9d0e3d'),
(2, 'user', '273a0c7bd3c679ba9a6f5d99078e36e85d02b952');
INSERT INTO `roles` (`id`, `role`) VALUES
(1, 'admin'),
(2, 'user');
INSERT INTO `user_roles` (`user_id`, `role_id`) VALUES
(1, 1),
(2, 2);
The password for admin is: 111111
The password for user is: 222222
24. 20 | P a g e
3. Models
According to the class diagram, the application will have the following models:
User
Role
Form
Simple Question
MC Question
Choice
Answered Simple Question
Answered MC Question
In this section, the code of the models and some explanation of the data annotations
used are to be provided. Please make sure that all the models are to be included in the
package “com.abahhar.formsapp.domain”.
3.1. User
package com.abahhar.formsapp.domain;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue
private Integer id;
private String login;
private String password;
//---------------------------------Navigation properties---------
------------------------//
@OneToOne(cascade=CascadeType.ALL)
@JoinTable(name="user_roles",
joinColumns = {@JoinColumn(name="user_id",
referencedColumnName="id")},
inverseJoinColumns = {@JoinColumn(name="role_id",
referencedColumnName="id")}
)
private Role role;
@OneToMany(mappedBy="user", cascade=CascadeType.REMOVE,
fetch=FetchType.EAGER)
private Set<SimpleAnswer> simpleAnswers;
@OneToMany(mappedBy="user", cascade=CascadeType.REMOVE,
fetch=FetchType.EAGER)
private Set<ChoiceAnswer> choiceAnswers;
25. 21 | P a g e
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public Set<SimpleAnswer> getSimpleAnswers() {
return simpleAnswers;
}
public void setSimpleAnswers(Set<SimpleAnswer> simpleAnswers) {
this.simpleAnswers = simpleAnswers;
}
public Set<ChoiceAnswer> getChoiceAnswers() {
return choiceAnswers;
}
public void setChoiceAnswers(Set<ChoiceAnswer> choiceAnswers) {
this.choiceAnswers = choiceAnswers;
}
}
26. 22 | P a g e
This is a regular Java class that you would create, the only thing that you might be
concerned about are the data annotations used, and here is an explanation for each:
Data Annotation Description
Entity
Used to declare a class as an entity to be
used in data access
Table
Used to specify the name of the table that
the model is going to be mapped to
Id
Used to specify that an attribute is the
primary key
GeneratedValue
Used to specify that an attribute is
automatically generated
“Auto_Increment”
OneToOne
Used to specify that a property will have
a one to one relationship with another
navigation property. Cascade attribute is
used to specify the type of cascade
JoinTable
Used to specify the name of the table that
will be used to join two tables, in this
model, the table “user_roles” is used to
join the “user” and “role” tables
JoinColumns
Used to specify to map the joined column
with the models properties, in this
example, “user_id” is mapped to the id of
this current class, and “role_id” is
mapped to the id of the Role class, since
the annotations are put above the
navigation property “role”
27. 23 | P a g e
OneToMany
Used to specify that the current class is
having a one-to-many relationship with
another navigation property, the user has
many simple answers and many choice
answers. MappedBy property specifies
which navigation property in the other
end is used for this class, for example,
mappedBy=user, means that
simpleAnswers and choiceAnswers will
have a navigation property called user,
which will be used for this relationship.
Cascade specifies the type of cascade.
Fetch specifies if the fetching is lazy or
eager.
28. 24 | P a g e
3.2. Role
package com.abahhar.formsapp.domain;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="roles")
public class Role {
@Id
@GeneratedValue
private Integer id;
private String role;
//---------------------------------Navigation properties---------
------------------------//
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="user_roles",
joinColumns = {@JoinColumn(name="role_id",
referencedColumnName="id")},
inverseJoinColumns = {@JoinColumn(name="user_id",
referencedColumnName="id")}
)
private Set<User> userRoles;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Set<User> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<User> userRoles) {
this.userRoles = userRoles;
}
}
29. 25 | P a g e
3.3. Form
package com.abahhar.formsapp.domain;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="forms")
public class Form {
@Id
@GeneratedValue
private Integer id;
@Column
private String title;
public Form(){
}
public Form(String title){
this.title = title;
}
//---------------------------------Navigation properties-------
--------------------------//
@OneToMany(mappedBy="form", cascade=CascadeType.REMOVE,
fetch=FetchType.EAGER)
private Set<Question> questions;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Set<Question> getQuestions() {
return questions;
}
public void setQuestions(Set<Question> questions) {
this.questions = questions;
}
}
30. 26 | P a g e
3.4. Question
package com.abahhar.formsapp.domain;
import javax.persistence.*;
@Entity
@Table(name="questions")
@Inheritance(strategy=InheritanceType.JOINED) //Joined strategy for
table per subclass
public class Question {
@Id
@GeneratedValue
private Integer id;
@Column
private String text;
public Question(){
}
public Question(String text){
this.text = text;
}
//---------------------------------Navigation properties-------
--------------------------//
@ManyToOne
@JoinColumn(name="form_id")
private Form form;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Form getForm() {
return form;
}
public void setForm(Form form) {
this.form = form;
}
}
31. 27 | P a g e
Since we are using inheritance and we want it to be mapped to the database schema,
@Inheritance data annotation is used to specify the strategy to be used. According to
the database schema, we are using the joined strategy.
To read more about this strategy and other strategies with applied examples, please
refer to the following article:
http://www.dineshonjava.com/p/implementing-inheritance-in-
hibernate.html#.VZuKlRuqqko
Also, @ManyToOne annotation is used for the relationship used between the form
and question. Since Form class contains @OneToMany, meaning one form to many
questions, then in the other side, which is Question class, we annotate the form
navigation property with @ManyToOne, meaning many questions to one form.
@JoinColumn is used to specify the foreign key to be mapped to in the Questions
table, which in this case is form_id, to be used to refer to the form.
3.5. SimpleQuestion
package com.abahhar.formsapp.domain;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="simplequestions")
public class SimpleQuestion extends Question {
public SimpleQuestion(){
super();
}
public SimpleQuestion(String text){
super(text);
}
//---------------------------------Navigation properties-------
--------------------------//
@OneToMany(mappedBy="simpleQuestion",
cascade=CascadeType.REMOVE, fetch=FetchType.EAGER)
private Set<SimpleAnswer> simpleAnswers;
public Set<SimpleAnswer> getSimpleAnswers() {
return simpleAnswers;
}
public void setSimpleAnswers(Set<SimpleAnswer> simpleAnswers) {
this.simpleAnswers = simpleAnswers;
}
}
32. 28 | P a g e
3.6. MCQuestion
package com.abahhar.formsapp.domain;
import java.util.Iterator;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="mcquestions")
public class MCQuestion extends Question {
public MCQuestion(){
super();
}
//---------------------------------Navigation properties-------
--------------------------//
@OneToMany(mappedBy="mcQuestion", cascade=CascadeType.REMOVE,
fetch=FetchType.EAGER)
private Set<Choice> choices;
@OneToMany(mappedBy="mcQuestion", cascade=CascadeType.REMOVE,
fetch=FetchType.EAGER)
private Set<ChoiceAnswer> choiceAnswers;
public Set<Choice> getChoices() {
return choices;
}
public void setChoices(Set<Choice> choices) {
this.choices = choices;
}
public Set<ChoiceAnswer> getChoiceAnswers() {
return choiceAnswers;
}
public void setChoiceAnswers(Set<ChoiceAnswer> choiceAnswers) {
this.choiceAnswers = choiceAnswers;
}
}
33. 29 | P a g e
3.7. Choice
package com.abahhar.formsapp.domain;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="choices")
public class Choice {
@Id
@GeneratedValue
private Integer id;
@Column
private String text;
public Choice(){
}
public Choice(String text){
this.text = text;
}
//---------------------------------Navigation properties-------
--------------------------//
@ManyToOne
@JoinColumn(name="question_id")
private MCQuestion mcQuestion;
@OneToMany(mappedBy="choice", cascade=CascadeType.REMOVE,
fetch=FetchType.EAGER)
private Set<ChoiceAnswer> choiceAnswers;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public MCQuestion getMcQuestion() {
return mcQuestion;
}
public void setMcQuestion(MCQuestion mcQuestion) {
this.mcQuestion = mcQuestion;
}
34. 30 | P a g e
public Set<ChoiceAnswer> getChoiceAnswers() {
return choiceAnswers;
}
public void setChoiceAnswers(Set<ChoiceAnswer> choiceAnswers) {
this.choiceAnswers = choiceAnswers;
}
}
3.8. SimpleAnswer
package com.abahhar.formsapp.domain;
import javax.persistence.*;
@Entity
@Table(name="simpleanswers")
public class SimpleAnswer {
@Id
@GeneratedValue
private Integer id;
@Column
private String text;
public SimpleAnswer(){
}
public SimpleAnswer(String text){
this.text = text;
}
//---------------------------------Navigation properties-------
--------------------------//
@ManyToOne
@JoinColumn(name="question_id")
private SimpleQuestion simpleQuestion;
@ManyToOne
@JoinColumn(name="user_id")
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
35. 31 | P a g e
this.text = text;
}
public SimpleQuestion getSimpleQuestion() {
return simpleQuestion;
}
public void setSimpleQuestion(SimpleQuestion simpleQuestion) {
this.simpleQuestion = simpleQuestion;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
3.9. ChoiceAnswer
package com.abahhar.formsapp.domain;
import javax.persistence.*;
@Entity
@Table(name="choiceanswers")
public class ChoiceAnswer {
@Id
@GeneratedValue
private Integer id;
public ChoiceAnswer(){
}
//---------------------------------Navigation properties-------
--------------------------//
@ManyToOne
@JoinColumn(name="question_id")
private MCQuestion mcQuestion;
@ManyToOne
@JoinColumn(name="choice_id")
private Choice choice;
@ManyToOne
@JoinColumn(name="user_id")
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
36. 32 | P a g e
}
public MCQuestion getMcQuestion() {
return mcQuestion;
}
public void setMcQuestion(MCQuestion mcQuestion) {
this.mcQuestion = mcQuestion;
}
public Choice getChoice() {
return choice;
}
public void setChoice(Choice choice) {
this.choice = choice;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
37. 33 | P a g e
4. Repositories
In this section, we create interfaces for the repositories that we will be using.
Repositories are used for the data access, this gives us a good separation of the data
access logic so we do not bother ourselves with when writing the logic. Also, all the
interfaces that we will be creating extend a ready interface that is called
JpaRepository, which we specify for it the type that we are dealing with and the type
of its primary key.
JpaRepository includes many built in methods that will help us in inserting, updating
and deleting the entity we are dealing with, which saves our time, because we will not
need to write anything for doing any transaction to the database.
4.1. UserRepository
package com.abahhar.formsapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abahhar.formsapp.domain.User;
public interface UserRepository extends JpaRepository<User, Integer>
{
public User findByLogin(String login);
}
4.2. RoleRepository
package com.abahhar.formsapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abahhar.formsapp.domain.Question;
public interface QuestionRepository<T extends Question>
extends JpaRepository<T, Integer> {
}
4.3. FormRepository
package com.abahhar.formsapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abahhar.formsapp.domain.Form;
public interface FormRepository extends JpaRepository<Form, Integer>
{
}
38. 34 | P a g e
4.4. QuestionRepository
package com.abahhar.formsapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abahhar.formsapp.domain.Question;
public interface QuestionRepository<T extends Question>
extends JpaRepository<T, Integer> {
}
4.5. SimpleQuestionRepository
package com.abahhar.formsapp.repository;
import com.abahhar.formsapp.domain.SimpleQuestion;
public interface SimpleQuestionRepository extends
QuestionRepository<SimpleQuestion> {
}
4.6. MCQuestionRepository
package com.abahhar.formsapp.repository;
import com.abahhar.formsapp.domain.MCQuestion;
public interface MCQuestionRepository extends
QuestionRepository<MCQuestion> {
}
4.7. ChoiceRepository
package com.abahhar.formsapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abahhar.formsapp.domain.Choice;
public interface ChoiceRepository extends JpaRepository<Choice,
Integer> {
}
39. 35 | P a g e
4.8. SimpleAnswerRepository
package com.abahhar.formsapp.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abahhar.formsapp.domain.SimpleAnswer;
import com.abahhar.formsapp.domain.SimpleQuestion;
import com.abahhar.formsapp.domain.User;
public interface SimpleAnswerRepository extends
JpaRepository<SimpleAnswer, Integer> {
}
4.9. ChoiceAnswerRepository
package com.abahhar.formsapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.abahhar.formsapp.domain.ChoiceAnswer;
public interface ChoiceAnswerRepository extends
JpaRepository<ChoiceAnswer, Integer> {
}
5. Services
In this section, we create the needed services to be used in the application. Services
provide us a good separation of the business logic that we need. Controllers use the
services, and the services use repositories, and with this we have a good separation of
concerns.
Please make sure that the services are in “com.abahhar.formsapp.service” package.
5.1. CustomUserDetailsService
package com.abahhar.formsapp.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import
org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import
org.springframework.security.core.userdetails.UserDetailsService;
40. 36 | P a g e
import
org.springframework.security.core.userdetails.UsernameNotFoundExcepti
on;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.repository.UserRepository;
@Service
@Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
public UserDetails loadUserByUsername(String login)
throws UsernameNotFoundException {
com.abahhar.formsapp.domain.User domainUser =
userRepository.findByLogin(login);
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new User(
domainUser.getLogin(),
domainUser.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(domainUser.getRole().getId())
);
}
public Collection<? extends GrantedAuthority>
getAuthorities(Integer role) {
List<GrantedAuthority> authList =
getGrantedAuthorities(getRoles(role));
return authList;
}
public List<String> getRoles(Integer role) {
List<String> roles = new ArrayList<String>();
if (role.intValue() == 1) {
roles.add("ROLE_USER");
roles.add("ROLE_ADMIN");
} else if (role.intValue() == 2) {
roles.add("ROLE_USER");
}
return roles;
}
public static List<GrantedAuthority>
getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new
ArrayList<GrantedAuthority>();
41. 37 | P a g e
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
This service will be used by Spring Security to do everything about authentication and
authorization with respect to the database. Also, it is the one specified in the spring-
security.xml configuration in the fragment of code:
<security:authentication-manager>
<security:authentication-provider user-service-
ref="customUserDetailsService">
<security:password-encoder hash="sha" />
</security:authentication-provider>
</security:authentication-manager>
Notice that the service is annotated with @Service annotations, to declare it as a
Spring Component, and it will be scanned for dependency injection.
Furthermore, @Transactional annotation is used. For information about this
annotation, please refer to the following link:
http://stackoverflow.com/questions/15300483/some-clarification-about-spring-
transactional-annotation-on-a-method
42. 38 | P a g e
5.2. UserService
package com.abahhar.formsapp.service;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.Role;
import com.abahhar.formsapp.domain.User;
import com.abahhar.formsapp.repository.RoleRepository;
import com.abahhar.formsapp.repository.UserRepository;
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
public User getUser(String login){
return userRepository.findByLogin(login);
}
public boolean registerUser(User user){
User loadedUser =
userRepository.findByLogin(user.getLogin());
if(loadedUser != null){
return false;
}
String hashedPassword =
DigestUtils.sha1Hex(user.getPassword());
Role role = roleRepository.findOne(2);
List<User> usersList = userRepository.findAll();
Set<User> userRoles = new HashSet<User>();
Iterator<User> iterator = usersList.iterator();
while(iterator.hasNext()){
User userRole = iterator.next();
//The admin doesn't need to have the ROLE_USER,
only users
if(userRole.getRole().getId() != 1){
userRoles.add(userRole);
}
}
userRoles.add(user);
role.setUserRoles(userRoles);
43. 39 | P a g e
user.setPassword(hashedPassword);
roleRepository.save(role);
return true;
}
}
This service is what we will use in the controllers to deal with users, as you notice, we
use two repositories here which are: UserRepository and RoleRepository. The
repositories are automatically injected by the framework since annotated with
@Autowired.
Also, we have two methods: getUser, which retrieves for us a user by his username,
and registerUser, which registers a user.
Please notice that in the registerUser we encrypt the password with sha1 encryption,
and we add the user role for the registered user, then save it in the database using the
repository.
5.3. RoleService
package com.abahhar.formsapp.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.Role;
import com.abahhar.formsapp.repository.RoleRepository;
@Service
@Transactional
public class RoleService {
@Autowired
private RoleRepository roleRepository;
public Role getRole(int id){
return roleRepository.findOne(id);
}
}
44. 40 | P a g e
5.4. FormService
package com.abahhar.formsapp.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.Form;
import com.abahhar.formsapp.repository.FormRepository;
@Service
@Transactional
public class FormService {
@Autowired
private FormRepository formRepository;
public Iterable<Form> findAll() {
return formRepository.findAll();
}
public Form save(Form entity) {
return formRepository.save(entity);
}
public void delete(Integer id) {
formRepository.delete(id);
}
public Form findOne(Integer id) {
return formRepository.findOne(id);
}
}
5.5. SimpleQuestionService
package com.abahhar.formsapp.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.SimpleQuestion;
import com.abahhar.formsapp.repository.SimpleQuestionRepository;
@Service
@Transactional
public class SimpleQuestionService {
@Autowired
private SimpleQuestionRepository simpleQuestionRepository;
public Iterable<SimpleQuestion> findAll() {
return simpleQuestionRepository.findAll();
}
public SimpleQuestion save(SimpleQuestion entity) {
return simpleQuestionRepository.save(entity);
45. 41 | P a g e
}
public void delete(Integer id) {
simpleQuestionRepository.delete(id);
}
public SimpleQuestion findOne(Integer id) {
return simpleQuestionRepository.findOne(id);
}
}
5.6. MCQuestionService
package com.abahhar.formsapp.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.MCQuestion;
import com.abahhar.formsapp.repository.MCQuestionRepository;
@Service
@Transactional
public class MCQuestionService {
@Autowired
private MCQuestionRepository mcQuestionRepository;
public Iterable<MCQuestion> findAll() {
return mcQuestionRepository.findAll();
}
public MCQuestion save(MCQuestion entity) {
return mcQuestionRepository.save(entity);
}
public void delete(Integer id) {
mcQuestionRepository.delete(id);
}
public MCQuestion findOne(Integer id) {
return mcQuestionRepository.findOne(id);
}
}
46. 42 | P a g e
5.7. ChoiceService
package com.abahhar.formsapp.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.Choice;
import com.abahhar.formsapp.repository.ChoiceRepository;
@Service
@Transactional
public class ChoiceService {
@Autowired
private ChoiceRepository choiceRepository;
public Iterable<Choice> findAll() {
return choiceRepository.findAll();
}
public Choice save(Choice entity) {
return choiceRepository.save(entity);
}
public void delete(Integer id) {
choiceRepository.delete(id);
}
public Choice findOne(Integer id) {
return choiceRepository.findOne(id);
}
}
5.8. SimpleAnswerService
package com.abahhar.formsapp.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.SimpleAnswer;
import com.abahhar.formsapp.domain.SimpleQuestion;
import com.abahhar.formsapp.domain.User;
import com.abahhar.formsapp.repository.SimpleAnswerRepository;
@Service
@Transactional
public class SimpleAnswerService {
@Autowired
private SimpleAnswerRepository simpleAnswerRepository;
public Iterable<SimpleAnswer> findAll() {
return simpleAnswerRepository.findAll();
47. 43 | P a g e
}
public SimpleAnswer save(SimpleAnswer entity) {
return simpleAnswerRepository.save(entity);
}
public void delete(Integer id) {
simpleAnswerRepository.delete(id);
}
public SimpleAnswer findOne(Integer id) {
return simpleAnswerRepository.findOne(id);
}
}
5.9. ChoiceAnswerService
package com.abahhar.formsapp.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.abahhar.formsapp.domain.ChoiceAnswer;
import com.abahhar.formsapp.repository.ChoiceAnswerRepository;
@Service
@Transactional
public class ChoiceAnswerService {
@Autowired
private ChoiceAnswerRepository choiceAnswerRepository;
public Iterable<ChoiceAnswer> findAll() {
return choiceAnswerRepository.findAll();
}
public ChoiceAnswer save(ChoiceAnswer entity) {
return choiceAnswerRepository.save(entity);
}
public void delete(Integer id) {
choiceAnswerRepository.delete(id);
}
public ChoiceAnswer findOne(Integer id) {
return choiceAnswerRepository.findOne(id);
}
}
48. 44 | P a g e
6. MCQuestion Wrapper Class
MCQuestionWrapper is a wrapper class that we will be using later in
MCQuestionController, to avoid any errors later, please make sure that this class exist
in “com.abahhar.formsapp.wrapper” package.
This class wraps an MCQuestion with the list of choices.
package com.abahhar.formsapp.wrapper;
import java.util.ArrayList;
import java.util.List;
import com.abahhar.formsapp.domain.Choice;
import com.abahhar.formsapp.domain.Form;
import com.abahhar.formsapp.domain.MCQuestion;
public class MCQuestionWrapper {
private MCQuestion mcQuestion;
private List<Choice> choices;
public MCQuestionWrapper(){
this.mcQuestion = new MCQuestion();
this.choices = new ArrayList<Choice>();
}
public MCQuestion getMcQuestion() {
return mcQuestion;
}
public void setMcQuestion(MCQuestion mcQuestion) {
this.mcQuestion = mcQuestion;
}
public List<Choice> getChoices() {
return choices;
}
public void setChoices(List<Choice> choices) {
this.choices = choices;
}
}
49. 45 | P a g e
7. Controllers
In this section, we create the proper controllers for the web application with proper
actions.
Please make sure that the controllers are in “com.abahhar.formsapp.controller”
package, except for HomeController, which is in “com.abahhar.formsapp” package.
7.1. Home Controller
package com.abahhar.formsapp;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
/**
* Simply selects the home view to render by returning its
name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView home() {
return new ModelAndView("redirect:/forms");
}
}
This controller contains the action home(), which you could access by going to URL
localhost/. The mapping of the URL to the action is specified by the value attribute in
the data annotation @RequestMapping, and the method specified is GET method.
This action redirects the user to “localhost/forms”. As you notice, the action returns
ModelAndView, which is a type that enables you to specify the path for the view to
return to, and enables you to include models and data to be returned to the view.
Another thing to notice is that if you want the Spring Framework to know that the
class is a Spring Controller “Component”, then you must put @Controller annotation
on the controller as done in this fragment of code, and you will notice in the package
explorer, the icon of the file will have a blue S on it, which means that this is a Spring
Component.
50. 46 | P a g e
7.2. SecurityNavigation Controller
This controller will handle the navigation for login, success-login and logout actions,
because we are using Spring MVC, we should make the controller with URL
mappings to the desired procedures, and this is what we are doing here:
package com.abahhar.formsapp.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.abahhar.formsapp.domain.User;
import com.abahhar.formsapp.service.UserService;
@Controller
public class SecurityNavigation {
@Autowired
UserService userService;
@RequestMapping(value="/user-login", method=RequestMethod.GET)
public ModelAndView loginForm() {
return new ModelAndView("login-form");
}
@RequestMapping(value="/error-login", method=RequestMethod.GET)
public ModelAndView invalidLogin() {
ModelAndView modelAndView = new ModelAndView("login-form");
modelAndView.addObject("error", true);
return modelAndView;
}
@RequestMapping(value="/success-login", method=RequestMethod.GET)
public ModelAndView successLogin() {
return new ModelAndView("success-login");
}
@RequestMapping(value="/users/register",
method=RequestMethod.GET)
public ModelAndView register(){
return new ModelAndView("users/register");
}
@RequestMapping(value="/users/register",
method=RequestMethod.POST)
public ModelAndView register(@ModelAttribute("user") User use
if(!userService.registerUser(user)){
return new
ModelAndView("users/register").addObject("error", true);
}
return new ModelAndView("login-form").addObject("registered",
true);}
}
As you notice, the controller contains proper actions for login, success-login, logout
and register. Also, you notice that we have UserService which is annotated with
@Autowired.
@ModelAttribute is used to set the name of the entity that is got from the form in the
view, the name of the entity should be contained in the name attribute of the form tag.
51. 47 | P a g e
7.3. FormsController
package com.abahhar.formsapp.controller;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.abahhar.formsapp.domain.Form;
import com.abahhar.formsapp.domain.MCQuestion;
import com.abahhar.formsapp.domain.Question;
import com.abahhar.formsapp.domain.SimpleQuestion;
import com.abahhar.formsapp.service.FormService;
@Controller
public class FormsController {
@Autowired
private FormService formService;
@RequestMapping(value="/forms", method=RequestMethod.GET)
public ModelAndView index(){
ModelAndView modelAndView = new
ModelAndView("forms/index");
modelAndView.addObject("forms", formService.findAll());
return modelAndView;
}
@RequestMapping(value="/forms/details",
method=RequestMethod.GET)
public ModelAndView details(@RequestParam Integer id){
ModelAndView modelAndView = new
ModelAndView("forms/details");
Form form = formService.findOne(id);
Set<SimpleQuestion> simpleQuestions = new
HashSet<SimpleQuestion>();
Set<MCQuestion> mcQuestions = new HashSet<MCQuestion>();
Iterator<Question> iterator =
form.getQuestions().iterator();
while(iterator.hasNext()){
Question question = iterator.next();
if(question instanceof SimpleQuestion){
SimpleQuestion simpleQuestion =
(SimpleQuestion) question;
simpleQuestions.add(simpleQuestion);
}else{
MCQuestion mcQuestion = (MCQuestion)
question;
52. 48 | P a g e
mcQuestions.add(mcQuestion);
}
}
modelAndView.addObject("form", formService.findOne(id));
modelAndView.addObject("simpleQuestions",
simpleQuestions);
modelAndView.addObject("mcQuestions", mcQuestions);
return modelAndView;
}
@RequestMapping(value="/forms/create",
method=RequestMethod.GET)
public String create(){
return "forms/create";
}
@RequestMapping(value="/forms/create",
method=RequestMethod.POST)
@ResponseBody
public ModelAndView create(@ModelAttribute("form") Form form){
formService.save(form);
return new ModelAndView("redirect:/forms");
}
@RequestMapping(value="/forms/update",
method=RequestMethod.GET)
public ModelAndView update(@RequestParam Integer id){
ModelAndView modelAndView = new
ModelAndView("forms/edit");
modelAndView.addObject("form", formService.findOne(id));
return modelAndView;
}
@RequestMapping(value="/forms/update",
method=RequestMethod.POST)
public ModelAndView update(@ModelAttribute("form") Form form){
ModelAndView modelAndView = new
ModelAndView("redirect:/forms/details?id="+form.getId().toString());
formService.save(form);
return modelAndView;
}
@RequestMapping(value="/forms/delete",
method=RequestMethod.GET)
public ModelAndView delete(@RequestParam Integer id){
ModelAndView modelAndView = new
ModelAndView("redirect:/forms");
formService.delete(id);
return modelAndView;
}
}
53. 49 | P a g e
The new thing here is @RequestParam annotation, this is used to specify that a
variable is got from the string parameters (e.g. /forms/update?id=1).
Another thing to notice is that when inserting and updating an entity, we use the save
method from the service. The save method could insert and update at the same time
because of the id of the entity, if the id doesn’t exist in the table, then the entity is new
and will be inserted, but if the id exists, it will update the existed one. All this is
handled automatically in the repository.
7.4. SimpleQuestionsController
package com.abahhar.formsapp.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.abahhar.formsapp.domain.Form;
import com.abahhar.formsapp.domain.SimpleQuestion;
import com.abahhar.formsapp.service.FormService;
import com.abahhar.formsapp.service.SimpleQuestionService;
@Controller
public class SimpleQuestionsController {
@Autowired
private SimpleQuestionService simpleQuestionService;
@Autowired
private FormService formService;
@RequestMapping(value="/simpleQuestions/details",
method=RequestMethod.GET)
public ModelAndView details(@RequestParam Integer id){
ModelAndView modelAndView = new
ModelAndView("simpleQuestions/details");
modelAndView.addObject("simpleQuestion",
simpleQuestionService.findOne(id));
return modelAndView;
}
@RequestMapping(value="/simpleQuestions/create",
method=RequestMethod.GET)
public ModelAndView create(@RequestParam Integer formId){
ModelAndView modelAndView = new
ModelAndView("simpleQuestions/create");
modelAndView.addObject("form",
formService.findOne(formId));
return modelAndView;
}
54. 50 | P a g e
@RequestMapping(value="/simpleQuestions/create",
method=RequestMethod.POST)
@ResponseBody
public ModelAndView create(@ModelAttribute("simpleQuestion")
SimpleQuestion simpleQuestion){
simpleQuestionService.save(simpleQuestion);
return new
ModelAndView("redirect:/forms/details?id="+simpleQuestion.getForm().g
etId().toString());
}
@RequestMapping(value="/simpleQuestions/update",
method=RequestMethod.GET)
public ModelAndView update(@RequestParam Integer id){
ModelAndView modelAndView = new
ModelAndView("simpleQuestions/edit");
modelAndView.addObject("simpleQuestion",
simpleQuestionService.findOne(id));
return modelAndView;
}
@RequestMapping(value="/simpleQuestions/update",
method=RequestMethod.POST)
public ModelAndView update(@ModelAttribute("simpleQuestion")
SimpleQuestion simpleQuestion){
simpleQuestion =
simpleQuestionService.save(simpleQuestion);
ModelAndView modelAndView = new
ModelAndView("redirect:/forms/details?id="+simpleQuestion.getForm().g
etId().toString());
return modelAndView;
}
@RequestMapping(value="/simpleQuestions/delete",
method=RequestMethod.GET)
public ModelAndView delete(@RequestParam Integer id){
Integer formId =
simpleQuestionService.findOne(id).getForm().getId();
ModelAndView modelAndView = new
ModelAndView("redirect:/forms/details?id="+formId.toString());
simpleQuestionService.delete(id);
return modelAndView;
}
}
55. 51 | P a g e
7.5. MCQuestionsController
package com.abahhar.formsapp.controller;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.abahhar.formsapp.domain.Choice;
import com.abahhar.formsapp.domain.Form;
import com.abahhar.formsapp.domain.MCQuestion;
import com.abahhar.formsapp.domain.SimpleQuestion;
import com.abahhar.formsapp.service.ChoiceService;
import com.abahhar.formsapp.service.FormService;
import com.abahhar.formsapp.service.MCQuestionService;
import com.abahhar.formsapp.wrapper.MCQuestionWrapper;
@Controller
public class MCQuestionsController {
@Autowired
private MCQuestionService mcQuestionService;
@Autowired
private ChoiceService choiceService;
@Autowired
private FormService formService;
@RequestMapping(value="/mcQuestions/details",
method=RequestMethod.GET)
public ModelAndView details(@RequestParam Integer id){
ModelAndView modelAndView = new
ModelAndView("mcQuestions/details");
modelAndView.addObject("mcQuestion",
mcQuestionService.findOne(id));
return modelAndView;
}
@RequestMapping(value="/mcQuestions/create",
method=RequestMethod.GET)
public ModelAndView create(@RequestParam Integer formId){
ModelAndView modelAndView = new
ModelAndView("mcQuestions/create");
MCQuestionWrapper mcQuestionWrapper = new
MCQuestionWrapper();
//add 4 choices to be filled
for(int i = 1; i <= 4; i++){
mcQuestionWrapper.getChoices().add(new Choice());
56. 52 | P a g e
}
modelAndView.addObject("form",
formService.findOne(formId));
modelAndView.addObject("mcQuestionWrapper",
mcQuestionWrapper);
return modelAndView;
}
@RequestMapping(value="/mcQuestions/create",
method=RequestMethod.POST)
@ResponseBody
public ModelAndView create(@ModelAttribute("mcQuestionWrapper")
MCQuestionWrapper mcQuestionWrapper){
MCQuestion mcQuestion =
mcQuestionWrapper.getMcQuestion();
List<Choice> choices = mcQuestionWrapper.getChoices();
mcQuestionService.save(mcQuestion);
Iterator<Choice> iterator = choices.iterator();
while(iterator.hasNext()){
Choice choice = iterator.next();
choice.setMcQuestion(mcQuestion);
choiceService.save(choice);
}
return new
ModelAndView("redirect:/forms/details?id="+mcQuestion.getForm().getId
().toString());
}
@RequestMapping(value="/mcQuestions/update",
method=RequestMethod.GET)
public ModelAndView update(@RequestParam Integer id){
ModelAndView modelAndView = new
ModelAndView("mcQuestions/edit");
MCQuestionWrapper mcQuestionWrapper = new
MCQuestionWrapper();
MCQuestion mcQuestion = mcQuestionService.findOne(id);
mcQuestionWrapper.setMcQuestion(mcQuestion);
Set<Choice> choices = mcQuestion.getChoices();
List<Choice> choicesList = new ArrayList<Choice>();
for(Iterator<Choice> iterator = choices.iterator();
iterator.hasNext(); ){
choicesList.add(iterator.next());
}
mcQuestionWrapper.setChoices(choicesList);
modelAndView.addObject("mcQuestionWrapper",
mcQuestionWrapper);
return modelAndView;
}
57. 53 | P a g e
@RequestMapping(value="/mcQuestions/update",
method=RequestMethod.POST)
public ModelAndView update(@ModelAttribute("mcQuestionWrapper")
MCQuestionWrapper mcQuestionWrapper){
MCQuestion mcQuestion =
mcQuestionWrapper.getMcQuestion();
List<Choice> choices = mcQuestionWrapper.getChoices();
mcQuestionService.save(mcQuestion);
mcQuestion =
mcQuestionService.findOne(mcQuestion.getId());
Iterator<Choice> iterator =
mcQuestion.getChoices().iterator();
while(iterator.hasNext()){
Integer choiceId = iterator.next().getId();
choiceService.delete(choiceId);
}
iterator = choices.iterator();
while(iterator.hasNext()){
Choice choice = iterator.next();
choice.setMcQuestion(mcQuestion);
choiceService.save(choice);
}
return new
ModelAndView("redirect:/forms/details?id="+mcQuestion.getForm().getId
().toString());
}
@RequestMapping(value="/mcQuestions/delete",
method=RequestMethod.GET)
public ModelAndView delete(@RequestParam Integer id){
Integer formId =
mcQuestionService.findOne(id).getForm().getId();
ModelAndView modelAndView = new
ModelAndView("redirect:/forms/details?id="+formId.toString());
mcQuestionService.delete(id);
return modelAndView;
}
}
58. 54 | P a g e
7.6. SimpleAnswerController
package com.abahhar.formsapp.controller;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.abahhar.formsapp.domain.SimpleAnswer;
import com.abahhar.formsapp.domain.SimpleQuestion;
import com.abahhar.formsapp.domain.User;
import com.abahhar.formsapp.service.SimpleAnswerService;
import com.abahhar.formsapp.service.SimpleQuestionService;
import com.abahhar.formsapp.service.UserService;
@Controller
public class SimpleAnswersController {
@Autowired
private SimpleAnswerService simpleAnswerService;
@Autowired
private SimpleQuestionService simpleQuestionService;
@Autowired
UserService userService;
@RequestMapping(value="/simpleAnswers/create",
method=RequestMethod.POST)
@ResponseBody
public ModelAndView create(@ModelAttribute("simpleAnswer")
SimpleAnswer simpleAnswer){
ModelAndView modelAndView = new
ModelAndView("redirect:/simpleQuestions/details?id="+simpleAnswer.get
SimpleQuestion().getId().toString());
String login =
SecurityContextHolder.getContext().getAuthentication().getName();
User user = userService.getUser(login);
simpleAnswer.setUser(user);
SimpleQuestion simpleQuestion =
simpleQuestionService.findOne(simpleAnswer.getSimpleQuestion().getId(
));
simpleAnswer.setSimpleQuestion(simpleQuestion);
simpleAnswerService.save(simpleAnswer);
return modelAndView;
}
@RequestMapping(value="/simpleAnswers/delete",
method=RequestMethod.GET)
59. 55 | P a g e
public ModelAndView delete(@RequestParam Integer answerId,
@RequestParam Integer questionId){
ModelAndView modelAndView = new
ModelAndView("redirect:/simpleQuestions/details?id="+questionId);
simpleAnswerService.delete(answerId);
return modelAndView;
}
}
The new thing here is that we are using the following statement to get the username of
the current user:
String login =
SecurityContextHolder.getContext().getAuthentication().getName();
Which with we get the entity of the user and set it to the simple answer, and because
of this assignment, the foreign key of the user id is set automatically after saving the
simple answer.
7.7. ChoiceAnswerController
package com.abahhar.formsapp.controller;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.abahhar.formsapp.domain.ChoiceAnswer;
import com.abahhar.formsapp.domain.MCQuestion;
import com.abahhar.formsapp.domain.User;
import com.abahhar.formsapp.service.ChoiceAnswerService;
import com.abahhar.formsapp.service.MCQuestionService;
import com.abahhar.formsapp.service.UserService;
@Controller
public class ChoiceAnswersController {
@Autowired
private ChoiceAnswerService choiceAnswerService;
@Autowired
private MCQuestionService mcQuestionService;
@Autowired
UserService userService;
60. 56 | P a g e
@RequestMapping(value="/choiceAnswers/create",
method=RequestMethod.POST)
@ResponseBody
public ModelAndView create(@ModelAttribute("choiceAnswer")
ChoiceAnswer choiceAnswer){
ModelAndView modelAndView = new
ModelAndView("redirect:/mcQuestions/details?id="+choiceAnswer.getMcQu
estion().getId().toString());
String login =
SecurityContextHolder.getContext().getAuthentication().getName();
User user = userService.getUser(login);
choiceAnswer.setUser(user);
MCQuestion mcQuestion =
mcQuestionService.findOne(choiceAnswer.getMcQuestion().getId());
choiceAnswer.setMcQuestion(mcQuestion);
choiceAnswerService.save(choiceAnswer);
return modelAndView;
}
@RequestMapping(value="/choiceAnswers/delete",
method=RequestMethod.GET)
public ModelAndView delete(@RequestParam Integer answerId,
@RequestParam Integer questionId){
ModelAndView modelAndView = new
ModelAndView("redirect:/mcQuestions/details?id="+questionId);
choiceAnswerService.delete(answerId);
return modelAndView;
}
}
61. 57 | P a g e
8. Views
8.1. login-form.jsp
<div class="container">
<h2 class="text-center">Login</h2>
<c:if test="${error == true}">
<p>
<b class="text-danger">Invalid login or
password.</b>
</p>
</c:if>
<c:if test="${registered == true}">
<p>
<b class="text-success">Successfully
registered, please enter credentials to login.</b>
</p>
</c:if>
<form class="form-horizontal" role="form" method="POST"
action="<c:url value="/j_spring_security_check"/>" >
<div class="form-group">
<label class="control-label col-sm-2"
for="j_username">Username:</label>
<div class="col-sm-10">
<input type="text" class="form-control"
name="j_username" id="j_username" placeholder="Enter username"
autofocus>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2"
for="j_password">Password:</label>
<div class="col-sm-10">
<input type="password" class="form-control"
name="j_password" id="j_password" placeholder="Enter password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-
default">Login</button>
</div>
</div>
</form>
Here we have two if statements, one to check the value of error, and the other to
check the value of registered. These two values are returned from the controller
through the statements with the following signature
“modelAndView.addObject(“NameOfVariable”, valueOfVariable)”.
If the if statement is satisfied, the content inside the tag will be written in the output.
<c:url /> tag is used to evaluate a statement that contains the current URL, followed
by the value of the “value” attribute.
62. 58 | P a g e
Please notice that “j_username” and “j_password” are the names of variables that
Spring Security deal with when passing the arguments from the views.
8.2. Users
8.2.1. Register.jsp
<div class="container">
<h2 class="text-center">Registration form</h2>
<c:if test="${error == true}">
<p>
<b class="text-danger">Username already
exists.</b>
</p>
</c:if>
<form class="form-horizontal" role="form" name="user"
method="POST" action="<c:url value="/users/register"/>" >
<div class="form-group">
<label class="control-label col-sm-2"
for="login">Username:</label>
<div class="col-sm-10">
<input type="text" class="form-control"
name="login" id="login" placeholder="Enter username" autofocus>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2"
for="password">Password:</label>
<div class="col-sm-10">
<input type="password" class="form-control"
name="password" id="password" placeholder="Enter password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-
default">Register</button>
</div>
</div>
</form>
63. 59 | P a g e
8.3. Forms
8.3.1. index.jsp
<sec:authorize access="hasRole('ROLE_ADMIN')">
<p>
<a href="<c:url value="/forms/create"/>"
class="btn btn-default btn-lg">Create form</a>
</p>
</sec:authorize>
<!-- Title -->
<div class="row">
<div class="col-lg-12">
<h3>Latest Forms</h3>
</div>
</div>
<!-- /.row -->
<c:choose>
<c:when test="${not empty forms }">
<!-- Page Features -->
<div class="row text-center">
<c:forEach var="form" items="${forms}">
<a href="<c:url
value="forms/details?id=${form.id}" />">
<div class="col-md-3 col-sm-6 hero-
feature">
<div class="thumbnail">
<img src="<c:url
value="/resources/img/form-icon.png" />" alt="">
<div class="caption">
<h3>${form.title}</h3>
<sec:authorize
access="hasRole('ROLE_ADMIN')">
<p>
<a href="<c:url
value="forms/update?id=${form.id}"/>" class="btn btn-
primary">Edit</a> <a href="<c:url
value="forms/delete?id=${form.id}"/>" class="btn btn-
default">Delete</a>
</p>
</sec:authorize>
</div>
</div>
</div>
</a>
</c:forEach>
</div>
<!-- /.row -->
</c:when>
<c:otherwise>
There are no forms
</c:otherwise>
</c:choose>
64. 60 | P a g e
Here we checked the role of the user using the tag <sec:authorize>, we check if the
user is with the role of admin, if the check is satisfied, the button for creating a form
will be displayed in the output.
Also, we used the tags <c:choose>, <c:when> and <c:otherwise>. When using the
choose tag, when will behave as an if statement with the condition in the test attribute,
and otherwise will behave as an else if the condition in the when tag is not satisfied.
Furthermore, we use the tag <c:foreach> to loop through the list of forms we have got
from the controller, we set each item in the list of forms to a variable which we called
“form”, then we used the properties of the form to display them in the page.
Please notice that to access the properties of an object in JSP pages, we include the
name of the property in ${} (e.g. ${form.title}).
Also, to use the authorize tag you should include this fragment of code after the
declaration of the xml file <?xml version=”1.0” encoding=”UTF-9”?>:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>