/**
* @author Anas A. Aljuwaiber
* @author Vaclav Hnizda
* @author Paul Pelafas
* Knowledge Box
* Project 2013-14
* SE491-591 - Software Engineering Studio
*/
package main;
import group.GroupFactory;
import group.GroupInfoJson;
import group.GroupStatusJson;
import hibernate.Answer;
import hibernate.Column;
import hibernate.Group;
import hibernate.Question;
import hibernate.Table;
import hibernate.User;
import hibernate.UserRoleGroup;
import hibernateLogic.APIKeyCheck;
import hibernateLogic.DatabasePro;
import hibernateLogic.DatabaseTools;
import hibernateLogic.ObjectRetrievalTools;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
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 question.QuestionDetailsJson;
import question.QuestionFactory;
import user.UserFactory;
import user.UserNameJson;
import user.UserQuestionJson;
import user.UserStatusJson;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
// The GroupController class is used to perform functions to an existing group or creation of a new group
@Controller
public class GroupController {
/**
* This API will create a new group for a given user
* @param groupName
* @param email
* @param password
* @param apiKey
* @return
* @throws Exception
*/
@RequestMapping(value = "group/create", method=RequestMethod.GET)
public @ResponseBody GroupStatusJson createGroup(
@RequestParam(value="groupName", required=true) String groupName,
@RequestParam(value="groupDescription", required=true) String groupDescription,
@RequestParam(value="userId", required=true) int userId,
@RequestParam(value="password", required=true) String password,
@RequestParam(value="apiKey", required=true) Integer apiKey) throws Exception
{
// ------ PSEUDO CODE FOR API group/create
// Check the that APIKey attached with the request is valid
// Setup the Database tools
// Check that the user exists
// If no, return false
// If yes, create a topic instance from the topicFactory
// apply data entry on the topic instance in the following tables
//1. t_topic
//2. rel_user_role_topic
// check the database to confirm previous data entry
// if it exists and is a valid topic, return true
// if not, return false
if (!APIKeyCheck.exists(apiKey))
{
throw new Exception("Failed to find your API Key!");
// Improve Error Handling with the following sites
// Also set up unique IDs for each error type.
// http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
// http://www.tutorialspoint.com/spring/spring_exception_handling_example.htm
}
else
{
// Set up your database Tools
DatabaseTools myTools = new DatabaseTools();
// Confirm user exists and has the correct password before letting them pass.
boolean userFound = myTools.dataSearch("User", "id", userId, "password", password);
// Return false if a user is not found or password incorrect!
if(!userFound)
{
return GroupFactory.validGroup(false);
}
else // If user verified
{
// See if the group already exists
boolean groupFound = myTools.dataSearch("Group", "groupTitle", groupName);
if(groupFound)
{
return GroupFactory.validGroup(false);
}
else
{
// create a topic instance from the GroupFactory
Group newGroup = GroupFactory.createGroup(groupName, groupDescription);
// apply data entry on the group instance
int newGroupID = myTools.dataEntry(newGroup);
// Creating the relational database entry - This is how the user and group are linked
UserRoleGroup newRelationship = new UserRoleGroup(userId, newGroupID, 1, newGroup.getCreateDate());
// Adding the relationship to the database
int newUserRoleGroup = myTools.dataEntry(newRelationship);
//Confirm Group exist by searching its id
// WILL NEED TO ADD LOGIC IN THE FUTURE TO CLEAN THINGS UP IF ONLY ONE IS ADDED AND NOT THE OTHER
boolean groupConfirmed = myTools.dataSearch("Group", "id", newGroupID);
boolean relationshipConfirmed = myTools.dataSearch("UserRoleGroup", "id", newUserRoleGroup);
// If successfully created and it exist in the database return true;
if(groupConfirmed && relationshipConfirmed)
{
return GroupFactory.validGroup(true);
}
// If not found create StatusOutput=FALSE and return
else
{
return GroupFactory.validGroup(false);
}
}
}
}
}
/**
* This API is used to delete a group
* @param groupId
* @param userId
* @param password
* @param apiKey
* @return is the status after the groups deletion
* @throws Exception
*/
@RequestMapping(value = "group/delete", method=RequestMethod.GET)
public @ResponseBody GroupStatusJson deleteGroup(
@RequestParam(value="groupId", required=true) int groupId,
@RequestParam(value="userId", required=true) int userId,
@RequestParam(value="password", required=true) String password,
@RequestParam(value="apiKey", required=true) Integer apiKey) throws Exception {
//check API key first
if (!APIKeyCheck.exists(apiKey)) {
throw new Exception("Failed to find your API Key!");
}
else {
// Set up your database Tools
DatabaseTools myTools = new DatabaseTools();
// Confirm user exists and has the correct password before letting them pass.
boolean userFound = myTools.dataSearch("User", "id", userId, "password", password);
// Return false if a user is not found or password incorrect!
if(!userFound) {
throw new Exception ("User not found");
}
else {
//check if group exists first
boolean groupFound = myTools.dataSearch("Group", "id", groupId);
//group not found
if(!groupFound) {
return GroupFactory.validGroup(false);
}
//group found
else {
//check to see if user has permission to delete group (admin)
//set up retrieval tools
ObjectRetrievalTools<UserRoleGroup> objTool = new ObjectRetrievalTools<UserRoleGroup>();
//return the UserRoleGroup
UserRoleGroup urg = (UserRoleGroup)objTool.getObject(Table.UserRoleGroup, "userId", userId, "groupId", groupId);
//get role id
int admin = urg.getRoleId();
//check for admin
if (admin == 0) {
throw new Exception ("User does not have admin privledges");
}
//admin confirmed
else {
boolean answer;
//first check to see if group has any questions first
//if there are questions, there will be answers as well
if (answer = myTools.dataSearch("Question", "groupId", groupId)){
//get all the questions associated with the group id
ObjectRetrievalTools<Question> objTool2 = new ObjectRetrievalTools<Question>();
List<Question> questionList = objTool2.getObjectList(Table.Question, "groupId", groupId);
//delete the questions from the db
for (Iterator<Question> questIterator = questionList.iterator(); questIterator.hasNext();) {
Question questionDelete = questIterator.next();
//get questionId for answer deletion
int questionId = questionDelete.getId();
myTools.dataRemoval(questionDelete);
//get all the answers associated with the question id
ObjectRetrievalTools<Answer> objTool3 = new ObjectRetrievalTools<Answer>();
List<Answer> answerList = objTool3.getObjectList(Table.Answer, "questionId", questionId);
//delete all the answers from the db
for (Iterator<Answer> ansIterator = answerList.iterator(); ansIterator.hasNext();) {
Answer answerDelete = ansIterator.next();
myTools.dataRemoval(answerDelete);
}
}
}
//group has no questions/answers
else {}
//get all the UserRoleGroup associated with the group id
//there should be at least 1 for the group creator
ObjectRetrievalTools<UserRoleGroup> objTool4 = new ObjectRetrievalTools<UserRoleGroup>();
List<UserRoleGroup> urgList = objTool4.getObjectList(Table.UserRoleGroup, "groupId", groupId);
//delete all the UserRoleGroup from db
for (Iterator<UserRoleGroup> iterator = urgList.iterator(); iterator.hasNext();) {
UserRoleGroup urgDelete = iterator.next();
myTools.dataRemoval(urgDelete);
}
//lastly, retrieve the actual group for deletion
ObjectRetrievalTools<Group> objTool5 = new ObjectRetrievalTools<Group>();
Group remGroup = (Group) objTool5.getObject(Table.Group, "id", groupId);
//call the tools to remove the group from the db
myTools.dataRemoval(remGroup);
//return true when group is deleted
return GroupFactory.validGroup(!myTools.dataSearch("Group", "id", groupId));
}
}
}
}
}
/**
* This method is used to return information regarding a group
* @param groupId
* @param userId
* @param password
* @param apiKey
* @return is the group information returned
* @throws Exception
*/
@RequestMapping(value = "group/info", method=RequestMethod.GET)
// GroupStatusJson is to be created
public @ResponseBody GroupInfoJson groupInfo(
@RequestParam(value="groupId", required=true) Integer groupId,
@RequestParam(value="userId", required=true) int userId,
@RequestParam(value="password", required=true) String password,
@RequestParam(value="apiKey", required=true) Integer apiKey) throws Exception
{
//check API key
if (!APIKeyCheck.exists(apiKey)){
throw new Exception ("Failed to find your API key");
}
else {
//load database tools
DatabaseTools myTools = new DatabaseTools();
//confirm user is valid
boolean userFound = myTools.dataSearch("User", "id", userId, "password", password);
if(!userFound){
throw new Exception ("User was not found");
}
else {
//confirm you can find the group based on ID
boolean groupConfirmed = myTools.dataSearch("Group", "id", groupId);
if (!groupConfirmed){
throw new Exception ("Group not found");
}
else {
// pull group using the ObjectRetrievalTools class
ObjectRetrievalTools<Group> retrieval = new ObjectRetrievalTools<Group>();
Group group = retrieval.getObject(Table.Group, "id", groupId);
// pass object to GroupFactory.createGroupInfoJson()
GroupInfoJson infoJson = GroupFactory.createGroupInfoJson(group);
return infoJson;
}
}
}
}
/**
* This API will be used to update a Group's title and description
* @param groupId
* @param groupTitle
* @param groupDesc
* @param userId
* @param password
* @param apiKey
* @return is the GroupInfoJson with the new information
* @throws Exception
*/
@RequestMapping(value = "group/update", method=RequestMethod.GET)
public @ResponseBody GroupStatusJson updateGroup(
@RequestParam(value="groupId", required=true) Integer groupId,
@RequestParam(value="groupTitle", required=true) String groupTitle,
@RequestParam(value="groupDescription", required=false) String groupDesc,
@RequestParam(value="userId", required=true) int userId,
@RequestParam(value="password", required=true) String password,
@RequestParam(value="apiKey", required=true) Integer apiKey) throws Exception {
if (!APIKeyCheck.exists(apiKey)){
throw new Exception ("Failed to find you API key");
}
else {
//set up db tools
DatabaseTools myTools = new DatabaseTools();
//check for valid user
boolean userFound = myTools.dataSearch("User", "id", userId, "password", password);
if (!userFound) {
throw new Exception ("User was not found");
}
else {
//check if group exists
boolean groupConfirmed = myTools.dataSearch("Group", "id", groupId);
if (!groupConfirmed){
throw new Exception ("Group not found");
}
else {
// pull group using the ObjectRetrievalTools class
ObjectRetrievalTools<Group> retrieval = new ObjectRetrievalTools<Group>();
//pull group object
Group group = retrieval.getObject(Table.Group, "id", groupId);
//call method in GroupFactory to update Group object
group = GroupFactory.updateGroup(group, groupTitle, groupDesc);
//send updated group back to db
myTools.dataUpdate(group);
//create a GroupStatusJson
GroupStatusJson statusJson = GroupFactory.validGroup(true);
return statusJson;
}
}
}
}
/**
* This API is used to return an list of all the questions under a specific group
* @param apiKey
* @param groupId
* @return
* @throws Exception
*/
@RequestMapping(value = "group/listAllQuestions", method=RequestMethod.GET)
public @ResponseBody QuestionDetailsJson[] getGroupList(
@RequestParam(value="apiKey", required=true) Integer apiKey,
@RequestParam(value="groupId", required=true) Integer groupId) throws Exception
{
// Checking that the API accessing the service is valid
if (!APIKeyCheck.exists(apiKey))
{
throw new Exception("Failed to find API key");
}
else
{
// set up database tool
DatabaseTools myTools = new DatabaseTools();
//first confirm the group with this id exists
boolean groupFound = myTools.dataSearch("Group", "id", groupId);
if (!groupFound)
{
throw new Exception("Failed to find a group with this id" );
}
else
{
// Tool used to pull objects
ObjectRetrievalTools objRetTools = new ObjectRetrievalTools();
//list to store all the Question objects associated with the groupId
List<Question> questionsList = objRetTools.getObjectList(Table.Question, "groupId", groupId);
//sets up the return object
QuestionDetailsJson[] questionDetailsList = QuestionFactory.createQuestionDetailsJson(questionsList.size());
// If there are no questions, return an array of size 0
// Does not work currently and passes to "else", due to exception thrown at Object Retrieval Tool
if(questionsList.size() == 0)
{
return new QuestionDetailsJson[0];
}
else
{
// Looping through to add the relevant info to the return array
for(int i = 0; i < questionsList.size(); i++)
{
// Instantiating the object QuestionDetailsJson at location i
questionDetailsList[i] = new QuestionDetailsJson();
// Copying the values from the questions list to the Json return objects list
questionDetailsList[i].setCreateDate(questionsList.get(i).getCreateDate());
questionDetailsList[i].setGroupId(questionsList.get(i).getGroupId());
questionDetailsList[i].setId(questionsList.get(i).getId());
questionDetailsList[i].setQuestionText(questionsList.get(i).getQuestionText());
questionDetailsList[i].setQuestionTypeId(questionsList.get(i).getQuestionTypeId());
}
}
return questionDetailsList;
}
}
}
/**
* This API is used to return all the questions for a user of a specific group
* @param groupId
* @param userId
* @param password
* @param apiKey
* @return is the array of user's questions in the group
* @throws Exception
*/
@RequestMapping(value = "group/listMyQuestions", method=RequestMethod.GET)
public @ResponseBody QuestionDetailsJson[] listMyQuestions(
@RequestParam(value="groupId", required=true) int groupId,
@RequestParam(value="userId", required=true) int userId,
@RequestParam(value="password", required=true) String password,
@RequestParam(value="apiKey", required=true) Integer apiKey) throws Exception {
if (!APIKeyCheck.exists(apiKey)){
throw new Exception("Failed to find your API key");
}
else {
//set up db tools
DatabasePro<User, Integer, String, Integer> myUserTools = new DatabasePro<>();
// Confirm user exists and has the correct password before letting them pass.
List<User> userFound = myUserTools.getTypeList(Table.User, Column.id, userId, Column.password, password);
if (userFound.size() == 0){
throw new Exception("User was not found");
}
else {
//check if group exists
DatabasePro<Group, Integer, Integer, String> myGroupTools = new DatabasePro<>();
List<Group> groupConfirmed = myGroupTools.getTypeList(Table.Group, Column.id, groupId);
if (groupConfirmed.size() == 0){
throw new Exception ("Group not found");
}
else {
//see if user is a part of the group
DatabasePro<UserRoleGroup, Integer, Integer, String> myUserRoleGroupTools = new DatabasePro<>();
List<UserRoleGroup> urgList = myUserRoleGroupTools.getTypeList(Table.UserRoleGroup, Column.groupId, groupId, Column.userId, userId);
//check list for size to determine if the user is part of the group
if (urgList.size() == 0) {
throw new Exception("User is not part of this group");
}
else {
//get the question list attributed to a specified user of a specified group
DatabasePro<Question, Integer, Integer, String> myQuestionTools = new DatabasePro<>();
List<Question> questionList = myQuestionTools.getTypeList(Table.Question, Column.groupId, groupId, Column.userId, userId);
int listSize = questionList.size();
//set up return object
QuestionDetailsJson[] userQuestions = QuestionFactory.createQuestionDetailsJson(listSize);
//counter for question loop
int counter = 0;
//this loop extracts all the questions from the list and creates a new QuestionJson for each.
for (Iterator<Question> questionIterator = questionList.iterator(); questionIterator.hasNext();) {
Question myQuestions = questionIterator.next();
//for each question, create a new QuesitonJson via the QuesitonFactory
QuestionDetailsJson questionJson = QuestionFactory.createQuestionDetailsJson(myQuestions);
//insert QuestionJson into the QuestionJson[] for return
userQuestions[counter] = questionJson;
counter++;
}
return userQuestions;
}
}
}
}
}
/**
* This API is used to return a Json list of all the users of a specific group
* @param groupId
* @param userId
* @param password
* @param apiKey
* @return is the UserNameJson array of names
* @throws Exception
*/
@RequestMapping(value = "group/listUsers", method=RequestMethod.GET)
public @ResponseBody UserNameJson[] listUsers(
@RequestParam(value="groupId", required=true) Integer groupId,
@RequestParam(value="userId", required=true) Integer userId,
@RequestParam(value="password", required=true) String password,
@RequestParam(value="apiKey", required=true) Integer apiKey) throws Exception{
if (!APIKeyCheck.exists(apiKey)){
throw new Exception("Failed to find your API key");
}
else {
//set up db tools
DatabaseTools myTools = new DatabaseTools();
boolean userFound = myTools.dataSearch("User", "id", userId, "password", password);
//verify user exists
if (!userFound){
throw new Exception("User not found");
}
else {
//set up pro tools
DatabasePro<UserRoleGroup, Integer, Integer, String> myProTools = new DatabasePro<>();
//list will either be 0 or 1 depending if the user was found
List<UserRoleGroup> groupBelongs = myProTools.getTypeList(Table.UserRoleGroup, Column.groupId, groupId, Column.userId, userId);
//empty list means user does not belong to the group
if (groupBelongs.size() == 0) {
throw new Exception("User does not belong to this group");
}
else {
//get the list of users in the group
List<UserRoleGroup> groupList = myProTools.getTypeList(Table.UserRoleGroup, Column.groupId, groupId);
//set up return object
UserNameJson[] userNameJsonArray = new UserNameJson[groupList.size()];
//for loop counter
int counter = 0;
for (Iterator<UserRoleGroup> userRoleGroupIterator = groupList.iterator(); userRoleGroupIterator.hasNext();) {
UserRoleGroup urg = userRoleGroupIterator.next();
//gets the user's id
int myId = urg.getUserId();
//get date joined
Date dateJoined = urg.getCreateDate();
//set up object retrieval tool
ObjectRetrievalTools<User> objRetrieval = new ObjectRetrievalTools<>();
//use retrieval tool with the user id to get the user object
User userObj = (User)objRetrieval.getObject(Table.User, "id", myId);
//extract the first and last name of the user
String firstName = userObj.getFirstName();
String lastName = userObj.getLastName();
//use the UserFactory to create a new UserNameJson object
UserNameJson userName = UserFactory.createUserNameJson(firstName, lastName, dateJoined);
//put the UserNameJson object in the array
userNameJsonArray[counter] = userName;
//increment the counter
counter++;
}
return userNameJsonArray;
}
}
}
}
/**
* This API is used to add an invited, existing user to a group
* @param groupId
* @param userId
* @param password
* @param invitedEmail
* @param apiKey
* @return
* @throws Exception
*/
@RequestMapping(value = "group/inviteUser", method=RequestMethod.GET)
public @ResponseBody UserStatusJson inviteUser(
@RequestParam(value="groupId", required=true) Integer groupId,
@RequestParam(value="userId", required=true) Integer userId,
@RequestParam(value="password", required=true) String password,
@RequestParam(value="invitedEmail", required=true) String invitedEmail,
@RequestParam(value="apiKey", required=true) Integer apiKey) throws Exception{
//API key check
if (!APIKeyCheck.exists(apiKey)) {
throw new Exception("Failed to find API key");
}
else {
//set up db tools
DatabaseTools myTools = new DatabaseTools();
boolean userFound = myTools.dataSearch("User", "id", userId, "password", password);
//verify user exists
if (!userFound){
throw new Exception("User not found");
}
else {
//set up pro tools
DatabasePro<UserRoleGroup, Integer, Integer, String> myProTools = new DatabasePro<>();
//list will either be 0 or 1 depending if the user was found
List<UserRoleGroup> groupBelongs = myProTools.getTypeList(Table.UserRoleGroup, Column.groupId, groupId, Column.userId, userId);
//empty list means user does not belong to the group
if (groupBelongs.size() == 0) {
throw new Exception("User does not belong to this group");
}
else {
boolean invitedUserExists = myTools.dataSearch("User", "email", invitedEmail);
if (!invitedUserExists) {
throw new Exception("Invited email is not currently an existing user");
}
else {
//set up object retrieval tools
ObjectRetrievalTools<User> userLookup = new ObjectRetrievalTools<>();
//retrieves the user object via their email address
User invitedUser = userLookup.getObject(Table.User, "email", invitedEmail);
//gets the invited users id
int invitedUserId = invitedUser.getId();
//creates a new joined date to be added to the UserRoleGroup
Date dateJoined = new Date();
//creates the new UserRoleGroup for the invited user
UserRoleGroup invitedUserUrg = new UserRoleGroup(invitedUserId, groupId, 0, dateJoined);
//enters the new UserRoleGroup into the db, effectively adding the invited user to the group
int newUserRoleGroupId = myTools.dataEntry(invitedUserUrg);
//check to see that the new UserRoleGroup was created properly
boolean relationshipConfirmed = myTools.dataSearch("UserRoleGroup", "id", newUserRoleGroupId);
//when failed to create the UserRoleGroup
if (!relationshipConfirmed){
return UserFactory.validUser(false);
}
else {
return UserFactory.validUser(true);
}
}
}
}
}
}
}