package com.lichtfragmente.servlets;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
import java.util.Vector;
import com.lichtfragmente.helpers.*;
import com.lichtfragmente.beans.NewsBean;
import com.lichtfragmente.beans.UserBean;
import com.lichtfragmente.beans.ImageBean;
/**
* Servlet managing a user's account page.
* This servlet manages all items to be appearing on a user's personal account page.
* It contains methods for fetching the count of unread messages, all information about
* the user itself and the latest images the user's friends have uploaded.
* Furthermore it contains the code for dispatching the views to the user which are shown
* in a modal dialog on the page and requested via AJAX. Furthermore, the same goes for
* POST messages which are also carried out via AJAX.
*
* All views associated with this servlet are located in the account/ folder of the jsp
* directory.
**/
public class AccountServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//check if the user is logged in
if (!GlobalHelpers.isLoggedIn(request)) {
response.sendRedirect("/lichtfragmente");
} else {
//deliver the view for changing the personal information
if (request.getParameter("editInfo")!=null) {
//get the current user's personal information
String userInfo=this.getUserInfo((Integer)request.getSession().getAttribute("userid"));
request.setAttribute("userinfo",userInfo);
//dispatch the view to the calling AJAX modal dialog
RequestDispatcher dispatcher=request.getRequestDispatcher("/WEB-INF/jsp/includes/account/editInfo.jsp");
dispatcher.forward(request,response);
} else if (request.getParameter("writeNews")!=null) {
//deliver the view for writing news atricles
RequestDispatcher dispatcher=request.getRequestDispatcher("/WEB-INF/jsp/includes/account/writeNews.jsp");
dispatcher.forward(request,response);
} else if (request.getParameter("uploadImg")!=null) {
//deliver the view for uploading images
RequestDispatcher dispatcher=request.getRequestDispatcher("/WEB-INF/jsp/includes/account/uploadImg.jsp");
dispatcher.forward(request,response);
} else if (request.getParameter("changePass")!=null) {
//deliver the view for changing the password
RequestDispatcher dispatcher=request.getRequestDispatcher("/WEB-INF/jsp/includes/account/changePass.jsp");
dispatcher.forward(request,response);
} else if (request.getParameter("manageUsers")!=null) {
//deliver the view for changing user access levels
//get user list
Vector<UserBean> list=this.getUserList();
request.setAttribute("users",list);
RequestDispatcher dispatcher=request.getRequestDispatcher("/WEB-INF/jsp/includes/account/manageUsers.jsp");
dispatcher.forward(request,response);
} else if (request.getParameter("delNews")!=null) {
//deliver the view for deleting news articles
//get list of articles
Vector<NewsBean> list=this.getNewsList();
request.setAttribute("news",list);
RequestDispatcher dispatcher=request.getRequestDispatcher("/WEB-INF/jsp/includes/account/delNews.jsp");
dispatcher.forward(request,response);
} else {
//this just delivers the normal account page (i.e. no modal dialog).
//this view is never requested via AJAX
HttpSession session=request.getSession();
//get account details
UserBean user=this.getAccountDetails((Integer)session.getAttribute("userid"));
if (user!=null) {
request.setAttribute("user",user);
//fetch number of unread messages
Integer newmsg=this.getNewMessageCount((Integer)session.getAttribute("userid"));
request.setAttribute("newmsg",newmsg);
//fetch friends images
Vector<ImageBean> friendsimages=this.getFriendsImages((Integer)session.getAttribute("userid"));
request.setAttribute("friendsimages",friendsimages);
RequestDispatcher dispatcher=request.getRequestDispatcher(GlobalHelpers.getIncludedUrl("account/account"));
dispatcher.forward(request,response);
} else {
//throw exception if the desired user doesn't exist
throw new ServletException("No user found!");
}
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out=response.getWriter();
int userid=(Integer)request.getSession().getAttribute("userid");
//check if the client is logged in
if (!GlobalHelpers.isLoggedIn(request)) {
response.sendRedirect("/lichtfragmente");
} else {
//handle the POST request for editing a users personal information
if (request.getParameter("editInfo")!=null) {
synchronized(this) {
try {
PreparedStatement stmt=DBInterface.doQuery("UPDATE users SET info=? WHERE id=?");
stmt.setString(1,request.getParameter("info"));
stmt.setInt(2,(Integer)request.getSession().getAttribute("userid"));
stmt.executeUpdate();
stmt.close();
DBInterface.close();
out.print("success");
} catch(SQLException se) {
throw new ServletException("Could not update information section: "+se.getMessage());
}
}
} else if (request.getParameter("writeNews")!=null) {
//handle the POST request for writing news atricles
//check if the user has the required privileges (>=Moderator)
if (GlobalHelpers.getUserLevel(userid)>=2) {
synchronized(this) {
try {
PreparedStatement stmt=DBInterface.doQuery("INSERT INTO news(title,author,content,date) VALUES (?,?,?,NOW())");
stmt.setString(1,request.getParameter("title"));
stmt.setInt(2,(Integer)request.getSession().getAttribute("userid"));
stmt.setString(3,request.getParameter("content"));
stmt.executeUpdate();
stmt.close();
DBInterface.close();
out.print("success");
} catch (SQLException se) {
throw new ServletException("Could not save news: "+se.getMessage());
}
}
}
} else if (request.getParameter("uploadImg")!=null) {
//handle the POST request for uploading images
//check privilieges (>=User)
if (GlobalHelpers.getUserLevel(userid)>=1) {
Integer imageid=FileUploadHelper.processFile(request,response,this.getServletContext().getRealPath("/"));
if (imageid!=null) {
//redirect the user to the newly uploaded image
response.sendRedirect("/lichtfragmente/image/"+imageid);
} else {
throw new ServletException("Problem uploading the image!");
}
}
} else if (request.getParameter("changePass")!=null) {
//handle the POST request for changing the password
synchronized(this) {
try {
//use MD5 to store the password in the database
PreparedStatement stmt=DBInterface.doQuery("UPDATE users SET password=md5(?) WHERE password=md5(?) AND id=?");
stmt.setString(1,request.getParameter("new"));
stmt.setString(2,request.getParameter("old"));
stmt.setInt(3,userid);
if (stmt.executeUpdate()!=0) {
out.print("success");
} else {
out.print("Could not update password!");
}
stmt.close();
DBInterface.close();
} catch (SQLException sql) {
throw new ServletException("Could not update password: "+sql.getMessage());
}
}
} else if (request.getParameter("manageUsers")!=null) {
//handle hte POST request for changing user permission levels
if (GlobalHelpers.getUserLevel(userid)>=3) {
//get array of user levels to change
String[] checked=request.getParameterValues("id");
synchronized(this) {
try {
//change each permission in the array accordingly
for (String id : checked) {
PreparedStatement stmt=DBInterface.doQuery("UPDATE users SET permissions=? WHERE id=?");
stmt.setInt(1,Integer.parseInt(request.getParameter("permissions_"+id)));
stmt.setInt(2,Integer.parseInt(id));
stmt.executeUpdate();
stmt.close();
}
DBInterface.close();
out.print("success");
} catch (SQLException sql) {
out.print("error: "+sql.getMessage());
}
}
}
} else if (request.getParameter("delNews")!=null) {
//handle the POST request for deleting news articles
//check privileges (>=Moderator)
if (GlobalHelpers.getUserLevel(userid)>=2) {
//array with ID of news to delete
String[] checked=request.getParameterValues("newsids");
synchronized(this) {
try {
//delete DB entry for each ID in the array
for (String id : checked) {
PreparedStatement stmt=DBInterface.doQuery("DELETE FROM news WHERE id=?");
stmt.setInt(1,Integer.parseInt(id));
stmt.executeUpdate();
stmt.close();
}
DBInterface.close();
out.print("success");
} catch (SQLException sql) {
out.print("error: "+sql.getMessage());
}
}
}
}
}
}
/**
* Retrieves count of unread messages.
* This method takes a user ID and fetches the number of unread messages
* for this very user from the database.
*
* @param userid The ID of the user for which we want to check the messages
* @return The number of unread messages for the given user
**/
private synchronized Integer getNewMessageCount(Integer userid)
throws ServletException {
Integer newmsg=new Integer(0);
try {
PreparedStatement stmt=DBInterface.doQuery("SELECT COUNT(id) FROM privatemessage " +
"WHERE recipient=? AND read=FALSE");
stmt.setInt(1,userid);
ResultSet result=stmt.executeQuery();
if (result.next()) {
newmsg=result.getInt(1);
}
} catch (SQLException sql) {
throw new ServletException("Could not retrieve messgae count: "+sql.getMessage());
}
return newmsg;
}
/**
* Get the list of news articles.
* This method fetches all news articles from the database which exits in the
* system as used in the view for deleting messages.
*
* @return A Vector containing the articles wrapped in beans.
**/
private Vector<NewsBean> getNewsList()
throws ServletException {
Vector<NewsBean> resultList=new Vector<NewsBean>();
synchronized(this) {
try {
//fetch articles and join it with the author names
PreparedStatement stmt=DBInterface.doQuery("SELECT n.id, u.name, n.title, n.date " +
"FROM news n " +
"INNER JOIN users u ON n.author=u.id " +
"ORDER BY \"date\" DESC");
ResultSet result=stmt.executeQuery();
//wrap the results into beans and add the to the list
while (result.next()) {
NewsBean temp=new NewsBean();
temp.setId(result.getInt(1));
temp.getUserBean().setName(result.getString(2));
temp.setTitle(result.getString(3));
temp.setDate(result.getTimestamp(4));
resultList.add(temp);
}
result.close();
stmt.close();
DBInterface.close();
} catch (SQLException se) {
throw new ServletException("Could not retrieve news: "+se.getMessage());
}
}
return resultList;
}
/**
* Fetches the list of users.
* This method retrieves a list of users along with their user ID, their name
* and their current permission levels from the database.
* The result is wrapped into a list of beans and used by the view which allows
* to change user levels.
*
* @return A Vector containing beans for all users in the system
**/
private synchronized Vector<UserBean> getUserList()
throws ServletException {
Vector<UserBean> list=new Vector<UserBean>();
try {
PreparedStatement stmt=DBInterface.doQuery("SELECT id,name,permissions FROM users ORDER BY name");
ResultSet result=stmt.executeQuery();
//wrap the results into beans and add them to the list
while (result.next()) {
UserBean temp=new UserBean();
temp.setId(result.getInt(1));
temp.setName(result.getString(2));
temp.setPermissions(result.getInt(3));
list.add(temp);
}
result.close();
stmt.close();
DBInterface.close();
} catch (SQLException sql) {
throw new ServletException("Could not read user list: "+sql.getMessage());
}
return list;
}
/**
* Retrieve personal information associated to a user.
* This method retrieves the personal information which is associated to a certain
* user ID from the database and returns it as a String.
*
* @param userid The ID of the user for which we want to get the information
* @return The personal information associated to the given user id
**/
private String getUserInfo(Integer userid) {
String info="";
synchronized(this) {
try {
//get information for a user id
PreparedStatement stmt=DBInterface.doQuery("SELECT info FROM users WHERE id=?");
stmt.setInt(1,userid);
ResultSet result=stmt.executeQuery();
if (result.next()) {
info=result.getString("info");
}
result.close();
stmt.close();
DBInterface.close();
} catch(SQLException se) {}
}
return info;
}
/**
* Retrieve all information associated to a user.
* This method retrieves all information which is associated to a certain
* user ID from the database and returns it as a String.
*
* @param userid The ID of the user for which we want to get the information
* @return All information associated to the given user id
**/
private UserBean getAccountDetails(Integer userid) {
if (userid==null) {
return null;
}
UserBean temp=new UserBean();
synchronized(this) {
try {
PreparedStatement stmt=DBInterface.doQuery("SELECT * FROM users WHERE id=?");
stmt.setInt(1,userid);
ResultSet result=stmt.executeQuery();
if (result.next()) {
temp.setId(userid);
temp.setName(result.getString("name"));
temp.setEmail(result.getString("email"));
temp.setFirstname(result.getString("firstname"));
temp.setLastname(result.getString("lastname"));
temp.setInfo(result.getString("info"));
temp.setPermissions(result.getInt("permissions"));
}
} catch (SQLException se) {}
}
return temp;
}
/**
* Retrieve friend's images.
* This method allows one to fetch the images of users the user with the given
* ID follows. It is returned as a list of beans.
*
* @param userid The user for which we want to know the friends images
* @return A list of images wrapped into beans from users this user follows
**/
private Vector<ImageBean> getFriendsImages(int userid)
throws ServletException {
Vector<ImageBean> list=new Vector<ImageBean>();
try {
PreparedStatement stmt=DBInterface.doQuery("SELECT i.id,i.title " +
"FROM user_has_follower uhf " +
"INNER JOIN image i ON i.owner=uhf.userid " +
"WHERE uhf.followerid=? " +
"ORDER BY i.date DESC LIMIT 7");
stmt.setInt(1,userid);
ResultSet result=stmt.executeQuery();
while (result.next()) {
ImageBean temp=new ImageBean();
temp.setId(result.getInt(1));
temp.setTitle(result.getString(2));
list.add(temp);
}
result.close();
stmt.close();
DBInterface.close();
} catch (SQLException se) {
throw new ServletException("Could not retrieve friend's images! "+se.getMessage());
}
return list;
}
}