/*
* Juick
* Copyright (C) 2008-2011, Ugnich Anton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package com.juick.http.www;
import com.juick.JuickApplication;
import com.juick.server.Endpoints;
import com.juick.server.UserQueries;
import com.juick.xmpp.Stream;
import org.springframework.jdbc.core.JdbcTemplate;
import ru.sape.Sape;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
/**
*
* @author Ugnich Anton
*/
@WebServlet(name = "Main", urlPatterns = {"/"})
@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxRequestSize = 1024 * 1024 * 10)
public class Main extends HttpServlet implements Stream.StreamListener {
static ExecutorService executorService;
JdbcTemplate sql;
JdbcTemplate sqlSearch;
Stream xmpp;
Home home = new Home();
Discover discover = new Discover();
PM pm = new PM();
Login login = new Login();
Help help = new Help();
User pagesUser = new User();
UserThread pagesUserThread = new UserThread();
NewMessage pagesNewMessage;
FacebookLogin loginFacebook = new FacebookLogin();
VKontakteLogin loginVK = new VKontakteLogin();
TwitterAuth twitterAuth;
SignUp signup = new SignUp();
Settings settings = new Settings();
RSS rss = new RSS();
JuickApplication app;
@Override
public void init() throws ServletException {
super.init();
try {
Properties conf = new Properties();
conf.load(getServletContext().getResourceAsStream("WEB-INF/juick.conf"));
twitterAuth = new TwitterAuth(conf.getProperty("twitter_consumer_key"),
conf.getProperty("twitter_consumer_secret"));
PageTemplates.sape = new Sape(conf.getProperty("sape_user"), "juick.com", 2000, 3600);
Endpoints.wwwJuickCom = conf.getProperty("www_juick_com", "juick.com");
app = new JuickApplication(conf, getServletContext().getRealPath("/"));
sql = app.getSql();
sqlSearch = app.getSqlSearch();
pagesNewMessage = new NewMessage(app);
} catch (Exception e) {
log("www failed", e);
}
}
@Override
public void onStreamFail(Exception e) {log("XMPP STREAM FAIL", e);}
@Override
public void onStreamReady() {
log("XMPP STREAM READY");
}
/**
* Handles the HTTP GET
method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getCharacterEncoding() == null) {
request.setCharacterEncoding("UTF-8");
}
String uri = request.getRequestURI();
if (uri.equals("/")) {
String tag = request.getParameter("tag");
if (tag != null) {
Utils.sendPermanentRedirect(response, "/tag/" + URLEncoder.encode(tag, "UTF-8"));
} else {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
home.doGet(sql, sqlSearch, request, response, visitor);
}
} else if (uri.equals("/post")) {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor != null) {
pagesNewMessage.doGetNewMessage(request, response, visitor);
} else {
Utils.sendTemporaryRedirect(response, "/login");
}
} else if (uri.equals("/login")) {
if (request.getQueryString() == null) {
login.doGetLoginForm(sql, request, response);
} else {
login.doGetLogin(sql, request, response);
}
} else if (uri.startsWith("/pm/")) {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor == null) {
Utils.sendTemporaryRedirect(response, "/login");
} else {
switch (uri) {
case "/pm/inbox":
pm.doGetInbox(sql, request, response, visitor);
break;
case "/pm/sent":
pm.doGetSent(sql, request, response, visitor);
break;
default:
Errors.doGet404(sql, request, response);
break;
}
}
} else if (uri.startsWith("/rss/")) {
String uname = uri.substring(5);
int uid = UserQueries.getUIDbyName(sql, uname);
if (uid > 0) {
rss.doGet(sql, request, response, uid, uname);
} else {
response.sendError(404);
}
} else if (uri.equals("/logout")) {
login.doGetLogout(sql, request, response);
} else if (uri.equals("/settings")) {
settings.doGet(sql, request, response);
} else if (uri.equals("/_fblogin")) {
loginFacebook.doGet(sql, request, response);
} else if (uri.equals("/_vklogin")) {
loginVK.doGet(sql, request, response);
} else if (uri.startsWith("/_twitter")) {
twitterAuth.doGet(sql, request, response);
} else if (uri.equals("/signup")) {
signup.doGet(sql, request, response);
} else if (uri.equals("/help") || uri.equals("/help/")) {
help.doRedirectToHelpIndex(sql, request, response);
} else if (uri.startsWith("/help/")) {
help.doGetHelp(sql, request, response);
} else if (uri.startsWith("/my_tags.json")) {
pagesUser.doMyTagsJson(sql, request, response);
} else if (uri.startsWith("/tag/")) {
discover.doGet(sql, sqlSearch, request, response);
} else if (uri.matches("^/\\d+$")) {
String strID = request.getRequestURI().substring(1);
int mid = 0;
try {
mid = Integer.parseInt(strID);
} catch (NumberFormatException e) {
}
if (mid > 0) {
com.juick.User author = com.juick.server.MessagesQueries.getMessageAuthor(sql, mid);
if (author != null) {
Utils.sendPermanentRedirect(response, "/" + author.getUName() + "/" + mid);
return;
}
}
Errors.doGet404(sql, request, response);
} else if (uri.matches("^/[^/]+$")) {
com.juick.User user = com.juick.server.UserQueries.getUserByName(sql, request.getRequestURI().substring(1));
if (user != null) {
Utils.sendPermanentRedirect(response, "/" + user.getUName() + "/");
} else {
Errors.doGet404(sql, request, response);
}
} else if (uri.matches("^/.+/.*")) {
String uriparts[] = uri.split("/");
com.juick.User user = com.juick.server.UserQueries.getUserByName(sql, uriparts[1]);
if (user != null && user.getUName().equals(uriparts[1]) && !user.Banned) {
if (uriparts.length == 2) { // http://juick.com/username/
pagesUser.doGetBlog(sql, sqlSearch, request, response, user);
} else if (uriparts[2].equals("tags")) {
pagesUser.doGetTags(sql, request, response, user);
} else if (uriparts[2].equals("friends")) {
pagesUser.doGetFriends(sql, request, response, user);
} else if (uriparts[2].equals("readers")) {
pagesUser.doGetReaders(sql, request, response, user);
} else {
int mid = 0;
try {
mid = Integer.parseInt(uriparts[2]);
} catch (NumberFormatException e) {
}
if (mid > 0) {
com.juick.User author = com.juick.server.MessagesQueries.getMessageAuthor(sql, mid);
if (author != null) {
if (!author.getUName().equals(user.getUName())) {
Utils.sendPermanentRedirect(response, "/" + author.getUName() + "/" + mid);
} else {
pagesUserThread.doGetThread(sql, request, response, mid);
}
} else {
Errors.doGet404(sql, request, response);
}
} else {
Errors.doGet404(sql, request, response);
}
}
} else if (user != null && !user.Banned) {
Utils.sendPermanentRedirect(response, "/" + user.getUName() + "/" + (uriparts.length > 2 ? uriparts[2] : ""));
} else {
Errors.doGet404(sql, request, response);
}
} else {
Errors.doGet404(sql, request, response);
}
}
/**
* Handles the HTTP POST
method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getCharacterEncoding() == null) {
request.setCharacterEncoding("UTF-8");
}
String uri = request.getRequestURI();
if (uri.equals("/post")) {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor != null && !visitor.Banned) {
pagesNewMessage.doPostMessage(request, response, visitor);
} else {
response.sendError(403);
}
} else if (uri.equals("/comment")) {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor != null && !visitor.Banned) {
pagesNewMessage.doPostComment(request, response, visitor);
} else {
response.sendError(403);
}
} else if (uri.equals("/like")) {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor != null && !visitor.Banned) {
pagesNewMessage.doPostRecomm(request, response, visitor);
} else {
response.sendError(403);
}
} else if (uri.equals("/pm/send")) {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor != null && !visitor.Banned) {
pm.doPostPM(sql, request, response, xmpp, visitor);
} else {
response.sendError(403);
}
} else if (uri.equals("/login")) {
login.doPostLogin(sql, request, response);
} else if (uri.equals("/signup")) {
signup.doPost(sql, request, response);
} else if (uri.equals("/settings")) {
settings.doPost(sql, request, response);
} else {
response.sendError(405);
}
}
@Override
public void destroy() {
super.destroy();
executorService.shutdown();
// Now deregister JDBC drivers in this context's ClassLoader:
// Get the webapp's ClassLoader
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// Loop through all drivers
Enumeration drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver.getClass().getClassLoader() == cl) {
// This driver was registered by the webapp's ClassLoader, so deregister it:
try {
log(String.format("Deregistering JDBC driver %s", driver.toString()));
DriverManager.deregisterDriver(driver);
} catch (SQLException ex) {
log(String.format("Error deregistering JDBC driver %s", driver), ex);
}
} else {
// driver was not registered by the webapp's ClassLoader and may be in use elsewhere
log(String.format("Not deregistering JDBC driver %s as it does not belong to this webapp's ClassLoader", driver));
}
}
}
}