aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/juick/CrosspostComponent.java65
-rw-r--r--src/main/java/com/juick/PushComponent.java119
-rw-r--r--src/main/java/com/juick/http/www/Discover.java4
-rw-r--r--src/main/java/com/juick/http/www/Errors.java16
-rw-r--r--src/main/java/com/juick/http/www/FacebookLogin.java80
-rw-r--r--src/main/java/com/juick/http/www/Help.java18
-rw-r--r--src/main/java/com/juick/http/www/Home.java5
-rw-r--r--src/main/java/com/juick/http/www/Login.java29
-rw-r--r--src/main/java/com/juick/http/www/Main.java73
-rw-r--r--src/main/java/com/juick/http/www/NewMessage.java34
-rw-r--r--src/main/java/com/juick/http/www/PM.java42
-rw-r--r--src/main/java/com/juick/http/www/PageTemplates.java105
-rw-r--r--src/main/java/com/juick/http/www/RSS.java24
-rw-r--r--src/main/java/com/juick/http/www/Settings.java29
-rw-r--r--src/main/java/com/juick/http/www/SignUp.java197
-rw-r--r--src/main/java/com/juick/http/www/TwitterAuth.java3
-rw-r--r--src/main/java/com/juick/http/www/User.java130
-rw-r--r--src/main/java/com/juick/http/www/UserThread.java15
-rw-r--r--src/main/java/com/juick/http/www/Utils.java4
-rw-r--r--src/main/java/com/juick/http/www/VKontakteLogin.java59
-rw-r--r--src/main/java/com/juick/server/protocol/JuickProtocol.java375
-rw-r--r--src/main/java/com/juick/server/protocol/ProtocolReply.java23
-rw-r--r--src/main/java/com/juick/server/protocol/annotation/UserCommand.java31
-rw-r--r--src/main/java/com/juick/xmpp/extensions/JuickMessage.java20
-rw-r--r--src/main/java/com/juick/xmpp/s2s/CleaningUp.java25
-rw-r--r--src/main/java/com/juick/xmpp/s2s/Connection.java10
-rw-r--r--src/main/java/com/juick/xmpp/s2s/ConnectionIn.java42
-rw-r--r--src/main/java/com/juick/xmpp/s2s/ConnectionListener.java35
-rw-r--r--src/main/java/com/juick/xmpp/s2s/ConnectionOut.java34
-rw-r--r--src/main/java/com/juick/xmpp/s2s/JuickBot.java185
-rw-r--r--src/main/java/com/juick/xmpp/s2s/XMPPComponent.java377
31 files changed, 1175 insertions, 1033 deletions
diff --git a/src/main/java/com/juick/CrosspostComponent.java b/src/main/java/com/juick/CrosspostComponent.java
index d5f13ab2..8b07583f 100644
--- a/src/main/java/com/juick/CrosspostComponent.java
+++ b/src/main/java/com/juick/CrosspostComponent.java
@@ -24,6 +24,9 @@ import com.juick.xmpp.Stream;
import com.juick.xmpp.StreamComponent;
import com.juick.xmpp.extensions.JuickMessage;
import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -35,11 +38,6 @@ import java.net.Socket;
import java.net.URL;
import java.net.URLEncoder;
import java.security.Key;
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.Enumeration;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
@@ -61,7 +59,7 @@ public class CrosspostComponent implements ServletContextListener, Stream.Strea
public final static String TWITTERURL = "https://api.twitter.com/1.1/statuses/update.json";
public final static String FBURL = "https://graph.facebook.com/me/feed";
public final static String VKURL = "https://api.vk.com/method/wall.post";
- Connection sql;
+ JdbcTemplate sql;
Stream xmpp;
String twitter_consumer_key;
String twitter_consumer_secret;
@@ -80,8 +78,7 @@ public class CrosspostComponent implements ServletContextListener, Stream.Strea
twitter_consumer_key = conf.getProperty("twitter_consumer_key", "");
twitter_consumer_secret = conf.getProperty("twitter_consumer_secret", "");
- setupSql(conf.getProperty("mysql_host"), conf.getProperty("mysql_username"),
- conf.getProperty("mysql_password", ""), conf.getProperty("mysql_database", ""));
+ setupSql(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver"), conf.getProperty("datasource_url", ""));
setupXmppComponent(conf.getProperty("xmpp_password", ""));
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
@@ -91,39 +88,15 @@ public class CrosspostComponent implements ServletContextListener, Stream.Strea
@Override
public void contextDestroyed(ServletContextEvent sce) {
- // Now deregister JDBC drivers in this context's ClassLoader:
- // Get the webapp's ClassLoader
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- // Loop through all drivers
- Enumeration<Driver> 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 {
- logger.info(String.format("Deregistering JDBC driver %s", driver.toString()));
- DriverManager.deregisterDriver(driver);
- } catch (SQLException ex) {
- logger.log(Level.SEVERE, 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
- logger.log(Level.SEVERE, String.format("Not deregistering JDBC driver %s as it does not belong to this webapp's ClassLoader", driver));
- }
- }
executorService.shutdown();
logger.info("component destroyed");
}
- public void setupSql(String host, String username, String password, String database) {
- try {
- Class.forName("com.mysql.jdbc.Driver");
- sql = DriverManager.getConnection(
- String.format("jdbc:mysql://%s/%s?autoReconnect=true&user=%s&password=%s",
- host, database, username, password));
- } catch (SQLException | ClassNotFoundException e) {
- logger.log(Level.SEVERE, e.getMessage(), e);
- }
+ public void setupSql(String driver, String url) {
+ DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(driver);
+ dataSource.setUrl(url);
+ sql = new JdbcTemplate(dataSource);
}
public void setupXmppComponent(String password) {
@@ -161,8 +134,8 @@ public class CrosspostComponent implements ServletContextListener, Stream.Strea
}
public boolean facebookPost(com.juick.Message jmsg) {
- String token = CrosspostQueries.getFacebookToken(sql, jmsg.getUser().getUID());
- if (token == null) {
+ String token = CrosspostQueries.getFacebookToken(sql, jmsg.getUser().getUID()).orElse("");
+ if (token.isEmpty()) {
return false;
}
@@ -198,8 +171,8 @@ public class CrosspostComponent implements ServletContextListener, Stream.Strea
}
public boolean vkontaktePost(com.juick.Message jmsg) {
- String tokens[] = CrosspostQueries.getVKTokens(sql, jmsg.getUser().getUID());
- if (tokens == null || tokens.length != 2) {
+ Pair<String, String> tokens = CrosspostQueries.getVKTokens(sql, jmsg.getUser().getUID()).orElse(Pair.of("", ""));
+ if (tokens.getLeft().isEmpty() || tokens.getRight().isEmpty()) {
return false;
}
@@ -209,7 +182,7 @@ public class CrosspostComponent implements ServletContextListener, Stream.Strea
boolean ret = false;
try {
- String body = "owner_id=" + tokens[0] + "&access_token=" + URLEncoder.encode(tokens[1], "UTF-8") + "&from_group=1&message=" + URLEncoder.encode(status, "UTF-8");
+ String body = "owner_id=" + tokens.getLeft() + "&access_token=" + URLEncoder.encode(tokens.getRight(), "UTF-8") + "&from_group=1&message=" + URLEncoder.encode(status, "UTF-8");
HttpsURLConnection conn = (HttpsURLConnection) new URL(VKURL).openConnection();
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
@@ -235,12 +208,12 @@ public class CrosspostComponent implements ServletContextListener, Stream.Strea
}
public boolean twitterPost(com.juick.Message jmsg) {
- String tokens[] = CrosspostQueries.getTwitterTokens(sql, jmsg.getUser().getUID());
- if (tokens == null || tokens.length != 2) {
+ Pair<String, String> tokens = CrosspostQueries.getTwitterTokens(sql, jmsg.getUser().getUID()).orElse(Pair.of("", ""));
+ if (tokens.getLeft().isEmpty() || tokens.getRight().isEmpty()) {
return false;
}
- String token = percentEncode(tokens[0]);
- String token_secret = percentEncode(tokens[1]);
+ String token = percentEncode(tokens.getLeft());
+ String token_secret = percentEncode(tokens.getRight());
logger.info("TWITTER: #" + jmsg.getMID());
diff --git a/src/main/java/com/juick/PushComponent.java b/src/main/java/com/juick/PushComponent.java
index 386448f4..3bb7cdc5 100644
--- a/src/main/java/com/juick/PushComponent.java
+++ b/src/main/java/com/juick/PushComponent.java
@@ -22,8 +22,8 @@ import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.juick.json.MessageSerializer;
-import com.juick.server.MessagesQueries;
import com.juick.server.PushQueries;
+import com.juick.server.SubscriptionsQueries;
import com.juick.xmpp.JID;
import com.juick.xmpp.Message.MessageListener;
import com.juick.xmpp.Stream;
@@ -45,21 +45,23 @@ import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.http.util.TextUtils;
import org.json.JSONObject;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;
import java.net.Socket;
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
*
@@ -72,7 +74,7 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
private ExecutorService executorService;
String wns_application_sip;
String wns_client_secret;
- Connection sql;
+ JdbcTemplate sql;
Socket socket;
Stream xmpp;
Sender GCMSender;
@@ -91,8 +93,7 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
wns_client_secret = conf.getProperty("wns_client_secret", "");
GCMSender = new Sender(conf.getProperty("gcm_key"));
- setupSql(conf.getProperty("mysql_host"), conf.getProperty("mysql_username"),
- conf.getProperty("mysql_password", ""), conf.getProperty("mysql_database", ""));
+ setupSql(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver"), conf.getProperty("datasource_url", ""));
setupXmppComponent(new JID("", conf.getProperty("push_jid"), ""), conf.getProperty("xmpp_host", "localhost"),
Integer.parseInt(conf.getProperty("xmpp_port", "5347")), conf.getProperty("push_xmpp_password", ""));
} catch (IOException e) {
@@ -103,39 +104,15 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
@Override
public void contextDestroyed(ServletContextEvent sce) {
- // Now deregister JDBC drivers in this context's ClassLoader:
- // Get the webapp's ClassLoader
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- // Loop through all drivers
- Enumeration<Driver> 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 {
- logger.info(String.format("Deregistering JDBC driver %s", driver.toString()));
- DriverManager.deregisterDriver(driver);
- } catch (SQLException ex) {
- logger.log(Level.SEVERE, 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
- logger.log(Level.SEVERE, String.format("Not deregistering JDBC driver %s as it does not belong to this webapp's ClassLoader", driver));
- }
- }
executorService.shutdown();
logger.info("component destroyed");
}
- public void setupSql(String host, String username, String password, String database) {
- try {
- Class.forName("com.mysql.jdbc.Driver");
- sql = DriverManager.getConnection(
- String.format("jdbc:mysql://%s/%s?autoReconnect=true&user=%s&password=%s",
- host, database, username, password));
- } catch (SQLException | ClassNotFoundException e) {
- logger.log(Level.SEVERE, e.getMessage(), e);
- }
+ public void setupSql(String driver, String url) {
+ DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(driver);
+ dataSource.setUrl(url);
+ sql = new JdbcTemplate(dataSource);
}
public void setupXmppComponent(JID jid, String host, int port, String password) {
@@ -161,38 +138,32 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
@Override
public void onMessage(com.juick.xmpp.Message msg) {
- JuickMessage jmsg = (JuickMessage) msg.getChild(JuickMessage.XMLNS);
- if (jmsg == null) {
- return;
- }
- logger.info("Message to push: " + msg.toString());
-
+ JuickMessage jmsg = (JuickMessage)msg.getChild(JuickMessage.XMLNS);
+ List<User> subscribedUsers = new ArrayList<>();
boolean isPM = jmsg.getMID() == 0;
boolean isReply = jmsg.getRID() > 0;
- int senderID = 0, recipientID = 0;
- if (isReply) {
- senderID = jmsg.getUser().getUID();
- }
+ int pmTo = 0;
if (isPM) {
- // PM
- try {
- recipientID = Integer.parseInt(msg.to.Username);
- } catch (NumberFormatException e) {
- logger.info("Wrong PM recipient: " + msg.to.Username);
- return;
+ pmTo = Integer.parseInt(msg.to.Username);
+ } else {
+ if (isReply) {
+ subscribedUsers =
+ SubscriptionsQueries.getUsersSubscribedToComments(sql, jmsg.getMID(), jmsg.getUser().getUID());
+ } else {
+ // new message
+ subscribedUsers = SubscriptionsQueries.getSubscribedUsers(sql, jmsg.getUser().getUID(), jmsg.getMID());
}
}
/*** ANDROID ***/
- List<String> regids;
+ final List<String> regids = new ArrayList<>();
if (isPM) {
- regids = new ArrayList<>();
- String targetId = PushQueries.getAndroidRegID(sql, recipientID);
- if (targetId != null && !targetId.isEmpty()) {
- regids.add(targetId);
- }
+ PushQueries.getAndroidRegID(sql, pmTo).ifPresent(regids::add);
} else {
- regids = isReply ? PushQueries.getAndroidSubscribersToComments(sql, jmsg.getMID(), senderID) : PushQueries.getAndroidSubscribers(sql, senderID);
+ List<Integer> uids = subscribedUsers.stream().map(User::getUID).collect(Collectors.toList());
+ if (uids.size() > 0) {
+ regids.addAll(PushQueries.getAndroidTokens(sql, uids));
+ }
}
if (!regids.isEmpty()) {
@@ -216,15 +187,14 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
}
/*** WinPhone ***/
- List<String> urls;
+ final List<String> urls = new ArrayList<>();
if (isPM) {
- urls = new ArrayList<>();
- String targetURL = PushQueries.getWinPhoneURL(sql, recipientID);
- if (!TextUtils.isEmpty(targetURL)) {
- urls.add(targetURL);
- }
+ PushQueries.getWinPhoneURL(sql, pmTo).ifPresent(urls::add);
} else {
- urls = isReply ? PushQueries.getWindowsSubscribersToComments(sql, jmsg.getMID(), senderID) :PushQueries.getWinPhoneSubscribers(sql, senderID);
+ List<Integer> uids = subscribedUsers.stream().map(User::getUID).collect(Collectors.toList());
+ if (uids.size() > 0) {
+ urls.addAll(PushQueries.getWindowsTokens(sql, uids));
+ }
}
@@ -262,15 +232,14 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
}
/*** iOS ***/
- List<String> tokens;
+ final List<String> tokens = new ArrayList<>();
if (isPM) {
- tokens = new ArrayList<>();
- String targetToken = PushQueries.getAPNSToken(sql, recipientID);
- if (targetToken != null && !targetToken.isEmpty()) {
- tokens.add(targetToken);
- }
+ PushQueries.getAPNSToken(sql, pmTo).ifPresent(tokens::add);
} else {
- tokens = isReply ? PushQueries.getAppleSubscribersToComments(sql, jmsg.getMID(), senderID) : PushQueries.getAPNSSubscribers(sql, senderID);
+ List<Integer> uids = subscribedUsers.stream().map(User::getUID).collect(Collectors.toList());
+ if (uids.size() > 0) {
+ tokens.addAll(PushQueries.getAPNSTokens(sql, uids));
+ }
}
if (!tokens.isEmpty()) {
ApnsService service = APNS.newService().withCert("/etc/juick/ios.p12", "juick")
diff --git a/src/main/java/com/juick/http/www/Discover.java b/src/main/java/com/juick/http/www/Discover.java
index e7d85d8a..bdb86380 100644
--- a/src/main/java/com/juick/http/www/Discover.java
+++ b/src/main/java/com/juick/http/www/Discover.java
@@ -20,6 +20,8 @@ package com.juick.http.www;
import com.juick.server.AdsQueries;
import com.juick.server.MessagesQueries;
import com.juick.server.TagQueries;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
@@ -37,7 +39,7 @@ import javax.servlet.http.HttpServletResponse;
*/
public class Discover {
- protected void doGet(Connection sql, Connection sqlSearch, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGet(JdbcTemplate sql, JdbcTemplate sqlSearch, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
String paramTagStr = URLDecoder.decode(request.getRequestURI().substring(5), "UTF-8");
diff --git a/src/main/java/com/juick/http/www/Errors.java b/src/main/java/com/juick/http/www/Errors.java
index f65b6201..0044c209 100644
--- a/src/main/java/com/juick/http/www/Errors.java
+++ b/src/main/java/com/juick/http/www/Errors.java
@@ -1,11 +1,12 @@
package com.juick.http.www;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.sql.Connection;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
/**
*
@@ -15,17 +16,16 @@ public class Errors {
public static String tagsHTML = null;
- public static void doGet404(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ public static void doGet404(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (tagsHTML == null) {
- tagsHTML = PageTemplates.getPopularTags(sql, 80);
+ tagsHTML = PageTemplates.formatPopularTags(sql, 80);
}
response.setStatus(404);
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
PageTemplates.pageHead(out, "404 Страница не найдена", null);
PageTemplates.pageNavigation(out, visitor, null);
PageTemplates.pageHomeColumn(out, sql, visitor);
@@ -37,8 +37,6 @@ public class Errors {
PageTemplates.pageFooter(request, out, visitor, false);
PageTemplates.pageEnd(out);
- } finally {
- out.close();
}
}
}
diff --git a/src/main/java/com/juick/http/www/FacebookLogin.java b/src/main/java/com/juick/http/www/FacebookLogin.java
index fcb08d6c..cf444abc 100644
--- a/src/main/java/com/juick/http/www/FacebookLogin.java
+++ b/src/main/java/com/juick/http/www/FacebookLogin.java
@@ -18,20 +18,19 @@
package com.juick.http.www;
import com.juick.server.UserQueries;
+import org.json.JSONObject;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.json.JSONObject;
/**
*
@@ -45,7 +44,7 @@ public class FacebookLogin {
private static final String FACEBOOK_SECRET = "95813bfb6ab8f473410c50d4f971649e";
private static final String FACEBOOK_REDIRECT = "http://juick.com/_fblogin";
- protected void doGet(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fbstate;
String code = request.getParameter("code");
@@ -132,61 +131,22 @@ public class FacebookLogin {
}
}
- private int getUIDbyFBID(Connection sql, long fbID) {
- int uid = 0;
- PreparedStatement stmt = null;
- ResultSet rs = null;
+ private int getUIDbyFBID(JdbcTemplate sql, long fbID) {
try {
- stmt = sql.prepareStatement("SELECT user_id FROM facebook WHERE fb_id=? AND user_id IS NOT NULL");
- stmt.setLong(1, fbID);
- rs = stmt.executeQuery();
- if (rs.first()) {
- uid = rs.getInt(1);
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ return sql.queryForObject("SELECT user_id FROM facebook WHERE fb_id=? AND user_id IS NOT NULL",
+ Integer.class, fbID);
+ } catch (EmptyResultDataAccessException e) {
+ return 0;
}
- return uid;
}
- private boolean insertDB(Connection sql, long fbID, String loginhash, String token, String fbName, String fbLink) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("INSERT INTO facebook(fb_id,loginhash,access_token,fb_name,fb_link) VALUES (?,?,?,?,?)");
- stmt.setLong(1, fbID);
- stmt.setString(2, loginhash);
- stmt.setString(3, token);
- stmt.setString(4, fbName);
- stmt.setString(5, fbLink);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean insertDB(JdbcTemplate sql, long fbID, String loginhash, String token, String fbName, String fbLink) {
+ return sql.update("INSERT INTO facebook(fb_id,loginhash,access_token,fb_name,fb_link) VALUES (?,?,?,?,?)",
+ fbID, loginhash, token, fbName, fbLink) > 0;
}
- private boolean updateDB(Connection sql, long fbID, String token, String fbName, String fbLink) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("UPDATE facebook SET access_token=?,fb_name=?,fb_link=? WHERE fb_id=?");
- stmt.setString(1, token);
- stmt.setString(2, fbName);
- stmt.setString(3, fbLink);
- stmt.setLong(4, fbID);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean updateDB(JdbcTemplate sql, long fbID, String token, String fbName, String fbLink) {
+ return sql.update("UPDATE facebook SET access_token=?,fb_name=?,fb_link=? WHERE fb_id=?",
+ token, fbName, fbLink, fbID) > 0;
}
}
diff --git a/src/main/java/com/juick/http/www/Help.java b/src/main/java/com/juick/http/www/Help.java
index 438fc3a9..503044e6 100644
--- a/src/main/java/com/juick/http/www/Help.java
+++ b/src/main/java/com/juick/http/www/Help.java
@@ -17,15 +17,12 @@
*/
package com.juick.http.www;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.sql.Connection;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.*;
/**
*
@@ -33,11 +30,11 @@ import javax.servlet.http.HttpServletResponse;
*/
public class Help {
- protected void doRedirectToHelpIndex(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doRedirectToHelpIndex(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Utils.sendTemporaryRedirect(response, "/help/ru/");
}
- protected void doGetHelp(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGetHelp(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
String path[] = request.getRequestURI().split("/");
@@ -64,8 +61,7 @@ public class Help {
}
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
PageTemplates.pageHead(out, "Помощь", null);
PageTemplates.pageNavigation(out, visitor, null);
@@ -81,8 +77,6 @@ public class Help {
PageTemplates.pageFooter(request, out, visitor, false);
PageTemplates.pageEnd(out);
- } finally {
- out.close();
}
}
diff --git a/src/main/java/com/juick/http/www/Home.java b/src/main/java/com/juick/http/www/Home.java
index d60e871d..d5c1bb7b 100644
--- a/src/main/java/com/juick/http/www/Home.java
+++ b/src/main/java/com/juick/http/www/Home.java
@@ -19,6 +19,8 @@ package com.juick.http.www;
import com.juick.server.AdsQueries;
import com.juick.server.MessagesQueries;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
@@ -35,7 +37,7 @@ import javax.servlet.http.HttpServletResponse;
*/
public class Home {
- protected void doGet(Connection sql, Connection sqlSearch, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
+ protected void doGet(JdbcTemplate sql, JdbcTemplate sqlSearch, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
int paramBefore = 0;
String paramBeforeStr = request.getParameter("before");
if (paramBeforeStr != null) {
@@ -65,6 +67,7 @@ public class Home {
title = "Микроблоги Juick: популярные записи";
mids = MessagesQueries.getPopular(sql, 0, paramBefore);
}
+
} else if (paramShow.equals("top")) {
Utils.sendPermanentRedirect(response, "/");
return;
diff --git a/src/main/java/com/juick/http/www/Login.java b/src/main/java/com/juick/http/www/Login.java
index 3e9c5e09..f12c7096 100644
--- a/src/main/java/com/juick/http/www/Login.java
+++ b/src/main/java/com/juick/http/www/Login.java
@@ -17,11 +17,10 @@
*/
package com.juick.http.www;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import java.io.IOException;
import java.io.PrintWriter;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@@ -33,7 +32,7 @@ import javax.servlet.http.HttpServletResponse;
*/
public class Login {
- protected void doGetLoginForm(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGetLoginForm(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor != null) {
Utils.sendTemporaryRedirect(response, "/");
@@ -41,8 +40,7 @@ public class Login {
}
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
@@ -182,12 +180,10 @@ public class Login {
out.println("</body>");
out.println("</html>");
- } finally {
- out.close();
}
}
- protected void doGetLogin(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGetLogin(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String hash = request.getQueryString();
if (hash.length() > 32) {
response.sendError(400);
@@ -204,7 +200,7 @@ public class Login {
}
}
- protected void doPostLogin(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doPostLogin(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username == null || password == null || username.length() > 32 || password.isEmpty()) {
@@ -230,19 +226,10 @@ public class Login {
}
}
- protected void doGetLogout(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGetLogout(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor != null) {
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("DELETE FROM logins WHERE user_id=?");
- stmt.setInt(1, visitor.getUID());
- stmt.executeUpdate();
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
+ sql.update("DELETE FROM logins WHERE user_id=?", visitor.getUID());
}
Cookie c = new Cookie("hash", "-");
diff --git a/src/main/java/com/juick/http/www/Main.java b/src/main/java/com/juick/http/www/Main.java
index 7896c207..63bf1c1f 100644
--- a/src/main/java/com/juick/http/www/Main.java
+++ b/src/main/java/com/juick/http/www/Main.java
@@ -21,6 +21,8 @@ import com.juick.server.UserQueries;
import com.juick.xmpp.JID;
import com.juick.xmpp.Stream;
import com.juick.xmpp.StreamComponent;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
import ru.sape.Sape;
import javax.servlet.ServletException;
@@ -32,9 +34,6 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.Socket;
import java.net.URLEncoder;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
import java.util.Properties;
/**
@@ -45,8 +44,8 @@ import java.util.Properties;
@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxRequestSize = 1024 * 1024 * 10)
public class Main extends HttpServlet implements Stream.StreamListener {
- Connection sql;
- Connection sqlSearch;
+ JdbcTemplate sql;
+ JdbcTemplate sqlSearch;
String sqlSearchConnStr = "jdbc:mysql://127.0.0.1:9306?autoReconnect=true&useUnicode=yes&characterEncoding=utf8&maxAllowedPacket=512000";
Stream xmpp;
Home home = new Home();
@@ -72,9 +71,14 @@ public class Main extends HttpServlet implements Stream.StreamListener {
Properties conf = new Properties();
conf.load(getServletContext().getResourceAsStream("/WEB-INF/juick.conf"));
- Class.forName("com.mysql.jdbc.Driver");
- sql = DriverManager.getConnection("jdbc:mysql://localhost/juick?autoReconnect=true&user=" + conf.getProperty("mysql_username", "") + "&password=" + conf.getProperty("mysql_password", ""));
- sqlSearch = null; // init this on search, timeout is too low
+ DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver"));
+ dataSource.setUrl(conf.getProperty("datasource_url"));
+ DriverManagerDataSource dataSourceSearch = new DriverManagerDataSource();
+ dataSourceSearch.setDriverClassName(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver"));
+ dataSourceSearch.setUrl(sqlSearchConnStr);
+ sql = new JdbcTemplate(dataSource);
+ sqlSearch = new JdbcTemplate(dataSourceSearch);
setupXmppComponent(conf.getProperty("xmpp_password"));
twitterAuth = new TwitterAuth(conf.getProperty("twitter_consumer_key"),
@@ -84,27 +88,7 @@ public class Main extends HttpServlet implements Stream.StreamListener {
log(null, e);
}
}
- public void closeSqlSearch() {
- if (sqlSearch != null) {
- try {
- sqlSearch.close();
- sqlSearch = null;
- } catch (SQLException e) {
- log("An error on closing sql search connection", e);
- }
- }
- };
- public Connection getSqlSearch() {
- if (sqlSearch == null) {
- try {
- sqlSearch = DriverManager.getConnection(sqlSearchConnStr, "", "");
- }
- catch (Exception e) {
- log("Couldn't open sqlSearch connection",e);
- }
- }
- return sqlSearch;
- }
+
public void setupXmppComponent(final String password) {
Thread thr = new Thread(() -> {
try {
@@ -120,33 +104,13 @@ public class Main extends HttpServlet implements Stream.StreamListener {
}
@Override
- public void onStreamFail(Exception e) {log("XMPP STREAM FAIL", e);}
+ public void onStreamFail(Exception e) {log("XMPP STREAM FAIL:" + e);}
@Override
public void onStreamReady() {
log("XMPP STREAM READY");
}
- @Override
- public void destroy() {
- super.destroy();
- if (sql != null) {
- try {
- sql.close();
- sql = null;
- } catch (SQLException e) {
- log(null, e);
- }
- }
- if (sqlSearch != null) {
- try {
- sqlSearch.close();
- sqlSearch = null;
- } catch (SQLException e) {
- log(null, e);
- }
- }
- }
/**
* Handles the HTTP <code>GET</code> method.
@@ -168,8 +132,7 @@ public class Main extends HttpServlet implements Stream.StreamListener {
Utils.sendPermanentRedirect(response, "/tag/" + URLEncoder.encode(tag, "UTF-8"));
} else {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- home.doGet(sql, getSqlSearch(), request, response, visitor);
- closeSqlSearch();
+ home.doGet(sql, sqlSearch, request, response, visitor);
}
} else if (uri.equals("/post")) {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
@@ -226,8 +189,7 @@ public class Main extends HttpServlet implements Stream.StreamListener {
} else if (uri.startsWith("/help/")) {
help.doGetHelp(sql, request, response);
} else if (uri.startsWith("/tag/")) {
- discover.doGet(sql, getSqlSearch(), request, response);
- closeSqlSearch();
+ discover.doGet(sql, sqlSearch, request, response);
} else if (uri.matches("^/\\d+$")) {
String strID = request.getRequestURI().substring(1);
int mid = 0;
@@ -255,8 +217,7 @@ public class Main extends HttpServlet implements Stream.StreamListener {
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, getSqlSearch(), request, response, user);
- closeSqlSearch();
+ 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")) {
diff --git a/src/main/java/com/juick/http/www/NewMessage.java b/src/main/java/com/juick/http/www/NewMessage.java
index 86725db7..642bd794 100644
--- a/src/main/java/com/juick/http/www/NewMessage.java
+++ b/src/main/java/com/juick/http/www/NewMessage.java
@@ -18,11 +18,7 @@
package com.juick.http.www;
import com.juick.Tag;
-import com.juick.server.CrosspostQueries;
-import com.juick.server.MessagesQueries;
-import com.juick.server.SubscriptionsQueries;
-import com.juick.server.TagQueries;
-import com.juick.server.UserQueries;
+import com.juick.server.*;
import com.juick.xmpp.JID;
import com.juick.xmpp.Message;
import com.juick.xmpp.Stream;
@@ -30,17 +26,18 @@ import com.juick.xmpp.extensions.JuickMessage;
import com.juick.xmpp.extensions.JuickUser;
import com.juick.xmpp.extensions.Nickname;
import com.juick.xmpp.extensions.XOOB;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
-import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
/**
*
@@ -48,10 +45,9 @@ import javax.servlet.http.HttpServletResponse;
*/
public class NewMessage {
- protected void doGetNewMessage(Connection sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
+ protected void doGetNewMessage(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
PageTemplates.pageHead(out, "Написать", "<script src=\"//maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=ABQIAAAAVVtPtxkw4soCEHg44FsNChRB4OFYjAXt73He16Zkp6a_0tPs2RTU6i6UlcMs4QvPBYvIY8rWvcxqOg\" type=\"text/javascript\"></script>"
+ "<script src=\"//static.juick.com/mc.js\" type=\"text/javascript\" defer=\"defer\"></script>"
+ "<script src=\"//static.juick.com/maps.js?2010111500\" type=\"text/javascript\" defer=\"defer\"></script>"
@@ -83,12 +79,10 @@ public class NewMessage {
PageTemplates.pageFooter(request, out, visitor, false);
PageTemplates.pageEnd(out);
- } finally {
- out.close();
}
}
- void printUserTags(Connection sql, PrintWriter out, com.juick.User visitor) {
+ void printUserTags(JdbcTemplate sql, PrintWriter out, com.juick.User visitor) {
List<Tag> tags = TagQueries.getUserTagsAll(sql, visitor.getUID());
if (tags.isEmpty()) {
@@ -134,7 +128,7 @@ public class NewMessage {
out.println("</p>");
}
- public void doPostMessage(Connection sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
+ public void doPostMessage(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
String body = request.getParameter("body");
if (body == null || body.length() < 1 || body.length() > 4096) {
response.sendError(400);
@@ -265,12 +259,12 @@ public class NewMessage {
out.println("<section id=\"content\">");
out.println("<h1>Сообщение опубликовано</h1>");
out.println("<p>Поделитесь своим новым постом в социальных сетях:</p>");
- if (CrosspostQueries.getTwitterTokens(sql, visitor.getUID()) == null) {
+ if (CrosspostQueries.getTwitterTokens(sql, visitor.getUID()).isPresent()) {
out.println("<p><a href=\"https://twitter.com/intent/tweet?text=" + URLEncoder.encode(sharetwi, "utf-8") + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-twi sharenew\">Отправить в Twitter</a></p>");
}
out.println("<p><a href=\"http://www.livejournal.com/update.bml?subject=" + URLEncoder.encode(hashtags, "utf-8") + "&event=" + sharelj + "&prop_taglist=" + URLEncoder.encode(tagscomma, "utf-8") + "\" target=\"_blank\" class=\"ico32-lj sharenew\">Отправить в LiveJournal</a></p>");
out.println("<p><a href=\"https://vk.com/share.php?url=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-vk sharenew\">Отправить в ВКонтакте</a></p>");
- if (CrosspostQueries.getFacebookToken(sql, visitor.getUID()) == null) {
+ if (CrosspostQueries.getFacebookToken(sql, visitor.getUID()).isPresent()) {
out.println("<p><a href=\"https://www.facebook.com/sharer/sharer.php?u=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-fb sharenew\">Отправить в Facebook</a></p>");
}
out.println("<p><a href=\"https://plus.google.com/share?url=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-gp sharenew\">Отправить в Google+</a></p>");
@@ -282,7 +276,7 @@ public class NewMessage {
}
}
- public void doPostComment(Connection sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
+ public void doPostComment(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
int mid = Utils.parseInt(request.getParameter("mid"), 0);
if (mid == 0) {
response.sendError(400);
@@ -383,7 +377,7 @@ public class NewMessage {
Utils.sendTemporaryRedirect(response, "/" + msg.getUser().getUName() + "/" + mid + "#" + ridnew);
}
- public void doPostRecomm(Connection sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
+ public void doPostRecomm(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
int mid = Utils.parseInt(request.getParameter("mid"), 0);
if (mid == 0) {
response.sendError(400);
diff --git a/src/main/java/com/juick/http/www/PM.java b/src/main/java/com/juick/http/www/PM.java
index a9505bdb..932d1baf 100644
--- a/src/main/java/com/juick/http/www/PM.java
+++ b/src/main/java/com/juick/http/www/PM.java
@@ -23,14 +23,14 @@ import com.juick.xmpp.JID;
import com.juick.xmpp.Message;
import com.juick.xmpp.Stream;
import com.juick.xmpp.extensions.JuickMessage;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.sql.Connection;
-import java.util.ArrayList;
-import java.util.List;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
/**
*
@@ -38,7 +38,7 @@ import javax.servlet.http.HttpServletResponse;
*/
public class PM {
- protected void doGetInbox(Connection sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
+ protected void doGetInbox(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
/*
int paramBefore = 0;
String paramBeforeStr = request.getParameter("before");
@@ -54,8 +54,7 @@ public class PM {
List<com.juick.Message> msgs = PMQueries.getLastPMInbox(sql, visitor.getUID());
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
PageTemplates.pageHead(out, title, null);
PageTemplates.pageNavigation(out, visitor, null);
PageTemplates.pageHomeColumn(out, sql, visitor);
@@ -64,8 +63,7 @@ public class PM {
if (!msgs.isEmpty()) {
out.println("<ul>");
- for (int i = msgs.size() - 1; i >= 0; i--) {
- com.juick.Message msg = msgs.get(i);
+ for (com.juick.Message msg : msgs) {
String txt = PageTemplates.formatMessage(msg.getText());
@@ -73,7 +71,7 @@ public class PM {
out.println(" <div class=\"msg-avatar\"><a href=\"/" + msg.getUser().getUName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUID() + ".png\" alt=\"" + msg.getUser().getUName() + "\"/></a></div>");
out.println(" <div class=\"msg-cont\">");
out.println(" <div class=\"msg-header\"><a href=\"/" + msg.getUser().getUName() + "/\">@" + msg.getUser().getUName() + "</a>:</div>");
- out.println(" <div class=\"msg-ts\"><a href=\"#\" onclick=\"return false\" title=\"" + msg.TimestampString + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.TimestampString) + "</a></div>");
+ out.println(" <div class=\"msg-ts\"><a href=\"#\" onclick=\"return false\" title=\"" + PageTemplates.sdfSQL.format(msg.getDate()) + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.getDate()) + "</a></div>");
out.println(" <div class=\"msg-txt\">" + txt + "</div>");
out.println(" <form action=\"/pm/send\" method=\"POST\" enctype=\"multipart/form-data\"><input type=\"hidden\" name=\"uname\" value=\"" + msg.getUser().getUName() + "\"/>");
@@ -97,12 +95,10 @@ public class PM {
PageTemplates.pageFooter(request, out, visitor, false);
PageTemplates.pageEnd(out);
- } finally {
- out.close();
}
}
- protected void doGetSent(Connection sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
+ protected void doGetSent(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
/*
int paramBefore = 0;
String paramBeforeStr = request.getParameter("before");
@@ -123,8 +119,7 @@ public class PM {
}
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
PageTemplates.pageHead(out, title, null);
PageTemplates.pageNavigation(out, visitor, null);
PageTemplates.pageHomeColumn(out, sql, visitor);
@@ -141,8 +136,7 @@ public class PM {
if (!msgs.isEmpty()) {
out.println("<ul>");
- for (int i = msgs.size() - 1; i >= 0; i--) {
- com.juick.Message msg = msgs.get(i);
+ for (com.juick.Message msg : msgs) {
String txt = PageTemplates.formatMessage(msg.getText());
@@ -150,7 +144,7 @@ public class PM {
out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/a/" + visitor.getUID() + ".png\"/></div>");
out.println(" <div class=\"msg-cont\">");
out.println(" <div class=\"msg-header\">→ <a href=\"/" + msg.getUser().getUName() + "/\">@" + msg.getUser().getUName() + "</a>:</div>");
- out.println(" <div class=\"msg-ts\"><a href=\"#\" onclick=\"return false\" title=\"" + msg.TimestampString + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.TimestampString) + "</a></div>");
+ out.println(" <div class=\"msg-ts\"><a href=\"#\" onclick=\"return false\" title=\"" + PageTemplates.sdfSQL.format(msg.getDate()) + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.getDate()) + "</a></div>");
out.println(" <div class=\"msg-txt\">" + txt + "</div>");
out.println(" </div>");
out.println(" </li>");
@@ -169,12 +163,10 @@ public class PM {
PageTemplates.pageFooter(request, out, visitor, false);
PageTemplates.pageEnd(out);
- } finally {
- out.close();
}
}
- public void doPostPM(Connection sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
+ public void doPostPM(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, Stream xmpp, com.juick.User visitor) throws ServletException, IOException {
String uname = request.getParameter("uname");
if (uname.startsWith("@")) {
uname = uname.substring(1);
@@ -200,7 +192,7 @@ public class PM {
msg.from = new JID("juick", "juick.com", null);
msg.to = new JID(Integer.toString(uid), "push.juick.com", null);
JuickMessage jmsg = new JuickMessage();
- jmsg.setUser(UserQueries.getUserByUID(sql, visitor.getUID()));
+ jmsg.setUser(visitor);
jmsg.setText(body);
msg.childs.add(jmsg);
xmpp.send(msg);
@@ -208,8 +200,8 @@ public class PM {
msg.to.Host = "ws.juick.com";
xmpp.send(msg);
- String jid = UserQueries.getJIDbyUID(sql, uid);
- if (jid != null) {
+ List<String> jids = UserQueries.getJIDsbyUID(sql, uid);
+ for (String jid : jids) {
Message mm = new Message();
mm.to = new JID(jid);
mm.type = Message.Type.chat;
diff --git a/src/main/java/com/juick/http/www/PageTemplates.java b/src/main/java/com/juick/http/www/PageTemplates.java
index fedb11bf..7021ccba 100644
--- a/src/main/java/com/juick/http/www/PageTemplates.java
+++ b/src/main/java/com/juick/http/www/PageTemplates.java
@@ -20,6 +20,7 @@ package com.juick.http.www;
import com.juick.Message;
import com.juick.Tag;
import com.juick.server.MessagesQueries;
+import com.juick.server.TagQueries;
import com.juick.server.UserQueries;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
@@ -35,7 +36,11 @@ import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.util.StringUtils;
import ru.sape.Sape;
/**
@@ -45,7 +50,7 @@ import ru.sape.Sape;
public class PageTemplates {
public static Sape sape = null;
- private static final SimpleDateFormat sdfSQL = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ protected static final SimpleDateFormat sdfSQL = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static SimpleDateFormat sdfSimple = new SimpleDateFormat("d MMM");
private static SimpleDateFormat sdfFull = new SimpleDateFormat("d MMM yyyy");
private static String tagsHTML = null;
@@ -105,13 +110,13 @@ public class PageTemplates {
out.println("</header>");
}
- public static void pageHomeColumn(PrintWriter out, Connection sql, com.juick.User visitor) {
+ public static void pageHomeColumn(PrintWriter out, JdbcTemplate sql, com.juick.User visitor) {
pageHomeColumn(out, sql, visitor, false);
}
- public static void pageHomeColumn(PrintWriter out, Connection sql, com.juick.User visitor, boolean showAdv) {
+ public static void pageHomeColumn(PrintWriter out, JdbcTemplate sql, com.juick.User visitor, boolean showAdv) {
if (tagsHTML == null) {
- tagsHTML = PageTemplates.getPopularTags(sql, 80);
+ tagsHTML = PageTemplates.formatPopularTags(sql, 80);
}
out.println("<aside id=\"column\">");
@@ -126,64 +131,10 @@ public class PageTemplates {
out.println("</aside>");
}
- public static String getPopularTags(Connection sql, int cnt) {
- String ret = "";
-
- PreparedStatement stmt = null;
- ResultSet rs = null;
- try {
- stmt = sql.prepareStatement("SELECT name FROM tags WHERE top=1 ORDER BY name ASC");
- rs = stmt.executeQuery();
- rs.beforeFirst();
- while (rs.next()) {
- if (!ret.isEmpty()) {
- ret += " ";
- }
- try {
- ret += "<a href=\"/tag/" + URLEncoder.encode(rs.getString(1), "UTF-8") + "\">" + Utils.encodeHTML(rs.getString(1)) + "</a>";
- } catch (UnsupportedEncodingException e) {
- }
-
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
- }
-
- return ret;
- }
-
- public static void printContestRating(PrintWriter out, Connection sql) {
- out.println("<hr/>");
- out.println("<!--noindex-->");
- out.println("<p style=\"font-size: 14pt\">Кто <a href=\"/help/ru/contest\">выиграет iPod</a>?</p>");
- out.println("<table width=\"100%\">");
-
- int i = 0;
- PreparedStatement stmt = null;
- ResultSet rs = null;
- try {
- stmt = sql.prepareStatement("SELECT users.id,users.nick,COUNT(users_refs.user_id) AS cnt FROM users INNER JOIN users_refs ON users.id=users_refs.ref WHERE users.id>2 GROUP BY users_refs.ref ORDER BY cnt DESC LIMIT 10");
- rs = stmt.executeQuery();
- rs.beforeFirst();
- while (rs.next()) {
- String uname = rs.getString(2);
- if (i == 0) {
- out.println(" <tr><td><b><a href=\"/" + uname + "/\">" + uname + "</a></b></td><td align=\"right\"><b>" + rs.getInt(3) + "</b></td></tr>");
- } else {
- out.println(" <tr><td><a href=\"/" + uname + "/\">" + uname + "</a></td><td align=\"right\">" + rs.getInt(3) + "</td></tr>");
- }
- i++;
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
- }
-
- out.println("</table>");
- out.println("<!--/noindex-->");
+ public static String formatPopularTags(JdbcTemplate sql, int cnt) {
+ List<String> popularTags = TagQueries.getPopularTags(sql).stream()
+ .map(t -> "<a href=\"/tag/" + URLEncoder.encode(t) + "\">" + Utils.encodeHTML(t) + "</a>").collect(Collectors.toList());
+ return StringUtils.collectionToDelimitedString(popularTags, " ");
}
public static void pageFooter(HttpServletRequest request, PrintWriter out, com.juick.User visitor, boolean sapeon) {
@@ -275,7 +226,7 @@ public class PageTemplates {
return ret;
}
- public static String formatDate(int minutes, String fulldate) {
+ public static String formatDate(int minutes, Date fulldate) {
if (minutes < 1) {
return "сейчас";
} else if (minutes < 60) {
@@ -314,17 +265,16 @@ public class PageTemplates {
}
return days + " " + unit + " назад";
} else {
- String ret = fulldate;
+ String ret = sdfFull.format(fulldate);
synchronized (sdfSQL) {
try {
- Date pDate = sdfSQL.parse(fulldate);
Calendar c = Calendar.getInstance();
int curyear = c.get(Calendar.YEAR);
- c.setTime(pDate);
+ c.setTime(fulldate);
if (c.get(Calendar.YEAR) == curyear) {
- ret = sdfSimple.format(pDate);
+ ret = sdfSimple.format(fulldate);
} else {
- ret = sdfFull.format(pDate);
+ ret = sdfFull.format(fulldate);
}
} catch (Exception e) {
System.err.println("PARSE EXCEPTION: " + fulldate);
@@ -334,20 +284,11 @@ public class PageTemplates {
}
}
- public static String formatJSLocalTime(String ts) {
- String ret = "";
- synchronized (sdfSQL) {
- try {
- Date date = sdfSQL.parse(ts);
- ret = "<script type=\"text/javascript\">"
- + "var d=new Date(" + date.getTime() + ");"
+ public static String formatJSLocalTime(Date ts) {
+ return "<script type=\"text/javascript\">"
+ + "var d=new Date(" + ts.getTime() + ");"
+ "document.write((d.getDate()<10?'0':'')+d.getDate()+'.'+(d.getMonth()<9?'0':'')+(d.getMonth()+1)+'.'+d.getFullYear()+' '+(d.getHours()<10?'0':'')+d.getHours()+':'+(d.getMinutes()<10?'0':'')+d.getMinutes());"
+ "</script>";
- } catch (Exception e) {
- System.err.println("PARSE EXCEPTION: " + ts);
- }
- }
- return ret;
}
public static String formatReplies(int replies) {
@@ -455,7 +396,7 @@ public class PageTemplates {
return msg;
}
- public static void printMessages(PrintWriter out, Connection sql, com.juick.User user, List<Integer> mids, com.juick.User visitor, int YandexID, int ad_mid) {
+ public static void printMessages(PrintWriter out, JdbcTemplate sql, com.juick.User user, List<Integer> mids, com.juick.User visitor, int YandexID, int ad_mid) {
List<com.juick.Message> msgs = MessagesQueries.getMessages(sql, mids);
for (int i = 0; i < msgs.size(); i++) {
@@ -501,7 +442,7 @@ public class PageTemplates {
out.println("<article data-mid=\"" + msg.getMID() + "\">");
out.println(" <aside><a href=\"/" + msg.getUser().getUName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUID() + ".png\" alt=\"" + msg.getUser().getUName() + "\"/></a></aside>");
out.println(" <header class=\"u\">@<a href=\"/" + msg.getUser().getUName() + "/\">" + msg.getUser().getUName() + "</a>:" + tagsStr + "</header>");
- out.println(" <header class=\"t\"><a href=\"/" + msg.getUser().getUName() + "/" + msg.getMID() + "\"><time datetime=\"" + msg.TimestampString + "Z\" title=\"" + msg.TimestampString + " GMT\">" + formatDate(msg.TimeAgo, msg.TimestampString) + "</time></a></header>");
+ out.println(" <header class=\"t\"><a href=\"/" + msg.getUser().getUName() + "/" + msg.getMID() + "\"><time datetime=\"" + sdfSQL.format(msg.getDate()) + "Z\" title=\"" + sdfSQL.format(msg.getDate()) + " GMT\">" + formatDate(msg.TimeAgo, msg.getDate()) + "</time></a></header>");
if (msg.AttachmentType != null) {
String fname = msg.getMID() + "." + msg.AttachmentType;
out.println(" <p class=\"ir\"><a href=\"//i.juick.com/photos-512/" + fname + "\" onclick=\"return showPhotoDialog('" + fname + "')\"><img src=\"//i.juick.com/photos-512/" + fname + "\" alt=\"\"/></a></p>");
diff --git a/src/main/java/com/juick/http/www/RSS.java b/src/main/java/com/juick/http/www/RSS.java
index 72893915..349743b5 100644
--- a/src/main/java/com/juick/http/www/RSS.java
+++ b/src/main/java/com/juick/http/www/RSS.java
@@ -19,16 +19,16 @@ package com.juick.http.www;
import com.juick.Message;
import com.juick.server.MessagesQueries;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
-import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.Iterator;
import java.util.List;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
/**
*
@@ -36,10 +36,9 @@ import javax.servlet.http.HttpServletResponse;
*/
public class RSS {
- private static final SimpleDateFormat sdfSQL = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final SimpleDateFormat sdfRSS = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
- protected void doGet(Connection sql, HttpServletRequest request, HttpServletResponse response, int uid, String uname) throws ServletException, IOException {
+ protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, int uid, String uname) throws ServletException, IOException {
List<Integer> mids = MessagesQueries.getUserBlog(sql, uid, 0, 0);
if (mids.isEmpty()) {
response.sendError(404);
@@ -73,14 +72,9 @@ public class RSS {
out.println("]]></title>");
out.println("<description><![CDATA[" + PageTemplates.formatMessage(msg.getText()) + "]]></description>");
- synchronized (sdfSQL) {
- try {
- Date date = sdfSQL.parse(msg.TimestampString);
- out.println("<pubDate>" + sdfRSS.format(date) + "</pubDate>");
- } catch (Exception e) {
- System.err.println("PARSE EXCEPTION: " + msg.TimestampString);
- }
- }
+ Date date = msg.getDate();
+ out.println("<pubDate>" + sdfRSS.format(date) + "</pubDate>");
+
out.println("<comments>http://juick.com/" + msg.getUser().getUName() + "/" + msg.getMID() + "</comments>");
if (!msg.Tags.isEmpty()) {
diff --git a/src/main/java/com/juick/http/www/Settings.java b/src/main/java/com/juick/http/www/Settings.java
index de37bdd0..54ee0ee9 100644
--- a/src/main/java/com/juick/http/www/Settings.java
+++ b/src/main/java/com/juick/http/www/Settings.java
@@ -17,15 +17,14 @@
*/
package com.juick.http.www;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
/**
*
@@ -33,12 +32,11 @@ import javax.servlet.http.HttpServletResponse;
*/
public class Settings {
- protected void doGet(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
PageTemplates.pageHead(out, "Логин", "");
PageTemplates.pageNavigation(out, visitor, null);
@@ -56,12 +54,10 @@ public class Settings {
PageTemplates.pageFooter(request, out, visitor, false);
PageTemplates.pageEnd(out);
- } finally {
- out.close();
}
}
- protected void doPost(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doPost(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username == null || password == null || username.length() > 32 || password.isEmpty()) {
@@ -79,16 +75,7 @@ public class Settings {
if (uid > 0) {
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("DELETE FROM logins WHERE user_id=?");
- stmt.setInt(1, uid);
- stmt.executeUpdate();
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
+ throw new IOException("Settings");
}
String referer = request.getHeader("Referer");
diff --git a/src/main/java/com/juick/http/www/SignUp.java b/src/main/java/com/juick/http/www/SignUp.java
index 64b62e48..1ee23386 100644
--- a/src/main/java/com/juick/http/www/SignUp.java
+++ b/src/main/java/com/juick/http/www/SignUp.java
@@ -18,16 +18,17 @@
package com.juick.http.www;
import com.juick.server.UserQueries;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
/**
*
@@ -35,7 +36,7 @@ import javax.servlet.http.HttpServletResponse;
*/
public class SignUp {
- protected void doGet(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
String type = request.getParameter("type");
@@ -61,8 +62,7 @@ public class SignUp {
}
response.setContentType("text/html; charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
+ try (PrintWriter out = response.getWriter()) {
PageTemplates.pageHead(out, "Новый пользователь", null);
PageTemplates.pageNavigation(out, visitor, null);
@@ -110,12 +110,10 @@ public class SignUp {
PageTemplates.pageFooter(request, out, visitor, false);
PageTemplates.pageEnd(out);
- } finally {
- out.close();
}
}
- protected void doPost(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doPost(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
int uid = 0;
@@ -204,170 +202,57 @@ public class SignUp {
response.sendRedirect("/");
}
- private boolean setUserRef(Connection sql, int uid, int ref) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("INSERT INTO users_refs(user_id,ref) VALUES (?,?)");
- stmt.setInt(1, uid);
- stmt.setInt(2, ref);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean setUserRef(JdbcTemplate sql, int uid, int ref) {
+ return sql.update("INSERT INTO users_refs(user_id,ref) VALUES (?,?)", uid, ref) > 0;
}
- private String getFacebookNameByHash(Connection sql, String hash) {
- String ret = null;
-
- PreparedStatement stmt = null;
- ResultSet rs = null;
+ private String getFacebookNameByHash(JdbcTemplate sql, String hash) {
try {
- stmt = sql.prepareStatement("SELECT fb_name,fb_link FROM facebook WHERE loginhash=?");
- stmt.setString(1, hash);
- rs = stmt.executeQuery();
- if (rs.first()) {
- ret = "<a href=\"" + rs.getString(2) + "\" rel=\"nofollow\">" + rs.getString(1) + "</a>";
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ return sql.queryForObject("SELECT fb_name,fb_link FROM facebook WHERE loginhash=?", String.class, hash);
+ } catch (EmptyResultDataAccessException e) {
+ return null;
}
-
- return ret;
}
- private String getTelegramNameByHash(Connection sql, String hash) {
- String ret = null;
-
- PreparedStatement stmt = null;
- ResultSet rs = null;
+ private String getTelegramNameByHash(JdbcTemplate sql, String hash) {
try {
- stmt = sql.prepareStatement("SELECT tg_name FROM telegram WHERE loginhash=?");
- stmt.setString(1, hash);
- rs = stmt.executeQuery();
- if (rs.first()) {
- ret = "<a href=\"https://telegram.me/" + rs.getString(1) + "\" rel=\"nofollow\">" + rs.getString(1) + "</a>";
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ String name = sql.queryForObject("SELECT tg_name FROM telegram WHERE loginhash=?", String.class, hash);
+ return "<a href=\"https://telegram.me/" + name + "\" rel=\"nofollow\">" + name + "</a>";
+ } catch (EmptyResultDataAccessException e) {
+ return null;
}
-
- return ret;
}
- private boolean setFacebookUser(Connection sql, String hash, int uid) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("UPDATE facebook SET user_id=?,loginhash=NULL WHERE loginhash=?");
- stmt.setInt(1, uid);
- stmt.setString(2, hash);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean setFacebookUser(JdbcTemplate sql, String hash, int uid) {
+ return sql.update("UPDATE facebook SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
}
- private String getVKNameByHash(Connection sql, String hash) {
- String ret = null;
-
- PreparedStatement stmt = null;
- ResultSet rs = null;
- try {
- stmt = sql.prepareStatement("SELECT vk_name,vk_link FROM vk WHERE loginhash=?");
- stmt.setString(1, hash);
- rs = stmt.executeQuery();
- if (rs.first()) {
- ret = "<a href=\"http://vk.com/" + rs.getString(2) + "\" rel=\"nofollow\">" + rs.getString(1) + "</a>";
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ private String getVKNameByHash(JdbcTemplate sql, String hash) {
+ List<Pair<String, String>> logins = sql.query("SELECT vk_name,vk_link FROM vk WHERE loginhash=?",
+ (rs, num) -> {
+ return Pair.of(rs.getString(1), rs.getString(2));
+ }, hash);
+ if (logins.size() > 0) {
+ return "<a href=\"http://vk.com/" + logins.get(0).getRight() + "\" rel=\"nofollow\">" + logins.get(0).getLeft() + "</a>";
}
-
- return ret;
+ return null;
}
- private boolean setVKUser(Connection sql, String hash, int uid) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("UPDATE vk SET user_id=?,loginhash=NULL WHERE loginhash=?");
- stmt.setInt(1, uid);
- stmt.setString(2, hash);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean setVKUser(JdbcTemplate sql, String hash, int uid) {
+ return sql.update("UPDATE vk SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
}
- private boolean setTelegramUser(Connection sql, String hash, int uid) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("UPDATE telegram SET user_id=?,loginhash=NULL WHERE loginhash=?");
- stmt.setInt(1, uid);
- stmt.setString(2, hash);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean setTelegramUser(JdbcTemplate sql, String hash, int uid) {
+ return sql.update("UPDATE telegram SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
}
- private String getJIDByHash(Connection sql, String hash) {
- String ret = null;
-
- PreparedStatement stmt = null;
- ResultSet rs = null;
+ private String getJIDByHash(JdbcTemplate sql, String hash) {
try {
- stmt = sql.prepareStatement("SELECT jid FROM jids WHERE loginhash=?");
- stmt.setString(1, hash);
- rs = stmt.executeQuery();
- if (rs.first()) {
- ret = rs.getString(1);
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ return sql.queryForObject("SELECT jid FROM jids WHERE loginhash=?", String.class, hash);
+ } catch (EmptyResultDataAccessException e) {
+ return null;
}
-
- return ret;
}
- private boolean setJIDUser(Connection sql, String hash, int uid) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("UPDATE jids SET user_id=?,loginhash=NULL WHERE loginhash=?");
- stmt.setInt(1, uid);
- stmt.setString(2, hash);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean setJIDUser(JdbcTemplate sql, String hash, int uid) {
+ return sql.update("UPDATE jids SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
}
}
diff --git a/src/main/java/com/juick/http/www/TwitterAuth.java b/src/main/java/com/juick/http/www/TwitterAuth.java
index ff02c28b..bbad4d83 100644
--- a/src/main/java/com/juick/http/www/TwitterAuth.java
+++ b/src/main/java/com/juick/http/www/TwitterAuth.java
@@ -7,6 +7,7 @@ import com.github.scribejava.core.oauth.OAuth10aService;
import com.github.scribejava.core.oauth.OAuthService;
import com.juick.server.UserQueries;
import org.json.JSONObject;
+import org.springframework.jdbc.core.JdbcTemplate;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
@@ -29,7 +30,7 @@ public class TwitterAuth {
this.consumerSecret = consumerSecret;
}
- protected void doGet(Connection sql, HttpServletRequest request, HttpServletResponse response)
+ protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String hash = "", request_token = "", request_token_secret = "";
String verifier = request.getParameter("oauth_verifier");
diff --git a/src/main/java/com/juick/http/www/User.java b/src/main/java/com/juick/http/www/User.java
index 84d1ad9a..0bdd910e 100644
--- a/src/main/java/com/juick/http/www/User.java
+++ b/src/main/java/com/juick/http/www/User.java
@@ -17,24 +17,22 @@
*/
package com.juick.http.www;
+import com.juick.Tag;
import com.juick.server.MessagesQueries;
import com.juick.server.TagQueries;
import com.juick.server.UserQueries;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
/**
*
@@ -42,7 +40,7 @@ import javax.servlet.http.HttpServletResponse;
*/
public class User {
- protected void doGetBlog(Connection sql, Connection sqlSearch, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
+ protected void doGetBlog(JdbcTemplate sql, JdbcTemplate sqlSearch, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
List<Integer> mids;
@@ -158,7 +156,7 @@ public class User {
}
}
- protected void doGetTags(Connection sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
+ protected void doGetTags(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor == null) {
@@ -181,7 +179,7 @@ public class User {
}
}
- protected void doGetFriends(Connection sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
+ protected void doGetFriends(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor == null) {
@@ -198,25 +196,14 @@ public class User {
out.println("<section id=\"content\">");
out.println("<table class=\"users\"><tr>");
- PreparedStatement stmt = null;
- ResultSet rs = null;
- try {
- stmt = sql.prepareStatement("SELECT users.id,users.nick FROM subscr_users INNER JOIN users ON subscr_users.user_id=users.id WHERE subscr_users.suser_id=? ORDER BY users.nick");
- stmt.setInt(1, user.getUID());
- rs = stmt.executeQuery();
- rs.beforeFirst();
- int cnt = 0;
- while (rs.next()) {
- if (cnt % 3 == 0 && cnt > 0) {
- out.print("</tr><tr>");
- }
- out.print("<td><a href=\"/" + rs.getString(2) + "/\"><img src=\"//i.juick.com/as/" + rs.getInt(1) + ".png\"/>" + rs.getString(2) + "</a></td>");
- cnt++;
+ List<com.juick.User> friends = UserQueries.getUserFriends(sql, user.getUID());
+ for (int i = 0; i < friends.size(); i++) {
+ if (i % 3 == 0 && i > 0) {
+ out.print("</tr><tr>");
}
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ out.print("<td><a href=\"/" + friends.get(i).getUName()
+ + "/\"><img src=\"//i.juick.com/as/" + friends.get(i).getUID() + ".png\"/>"
+ + friends.get(i).getUName() + "</a></td>");
}
out.println("</tr></table>");
@@ -227,7 +214,7 @@ public class User {
}
}
- protected void doGetReaders(Connection sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
+ protected void doGetReaders(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (visitor == null) {
@@ -244,25 +231,14 @@ public class User {
out.println("<section id=\"content\">");
out.println("<table class=\"users\"><tr>");
- PreparedStatement stmt = null;
- ResultSet rs = null;
- try {
- stmt = sql.prepareStatement("SELECT users.id,users.nick FROM subscr_users INNER JOIN users ON subscr_users.suser_id=users.id WHERE subscr_users.user_id=? ORDER BY users.nick");
- stmt.setInt(1, user.getUID());
- rs = stmt.executeQuery();
- rs.beforeFirst();
- int cnt = 0;
- while (rs.next()) {
- if (cnt % 3 == 0 && cnt > 0) {
- out.print("</tr><tr>");
- }
- out.print("<td><a href=\"/" + rs.getString(2) + "/\"><img src=\"//i.juick.com/as/" + rs.getInt(1) + ".png\"/>" + rs.getString(2) + "</a></td>");
- cnt++;
+ List<com.juick.User> readers = UserQueries.getUserReaders(sql, user.getUID());
+ for (int i = 0; i < readers.size(); i++) {
+ if (i % 3 == 0 && i > 0) {
+ out.print("</tr><tr>");
}
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ out.print("<td><a href=\"/" + readers.get(i).getUName()
+ + "/\"><img src=\"//i.juick.com/as/" + readers.get(i).getUID() + ".png\"/>"
+ + readers.get(i).getUName() + "</a></td>");
}
out.println("</tr></table>");
@@ -285,7 +261,7 @@ public class User {
}
}
- public static void pageUserColumn(PrintWriter out, Connection sql, com.juick.User user, com.juick.User visitor) {
+ public static void pageUserColumn(PrintWriter out, JdbcTemplate sql, com.juick.User user, com.juick.User visitor) {
out.println("<aside id=\"column\">");
out.println(" <div id=\"ctitle\"><a href=\"./\"><img src=\"//i.juick.com/as/" + user.getUID() + ".png\" alt=\"\"/>" + user.getUName() + "</a></div>");
if (visitor != null && visitor.getUID() > 0 && visitor.getUID() != user.getUID()) {
@@ -342,56 +318,22 @@ public class User {
out.println("</aside>");
}
- public static String pageUserTags(Connection sql, com.juick.User user, com.juick.User visitor, int cnt) {
- com.juick.Tag tags[] = null;
-
- int maxUsageCnt = 0;
- PreparedStatement stmt = null;
- ResultSet rs = null;
- try {
- if (cnt > 0) {
- stmt = sql.prepareStatement("SELECT tags.name AS name,COUNT(DISTINCT messages_tags.message_id) AS cnt FROM (messages INNER JOIN messages_tags ON (messages.message_id=messages_tags.message_id)) INNER JOIN tags ON messages_tags.tag_id=tags.tag_id WHERE messages.user_id=? GROUP BY messages_tags.tag_id ORDER BY cnt DESC LIMIT ?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
- stmt.setInt(1, user.getUID());
- stmt.setInt(2, cnt);
- } else {
- stmt = sql.prepareStatement("SELECT tags.name AS name,COUNT(DISTINCT messages_tags.message_id) AS cnt FROM (messages INNER JOIN messages_tags ON (messages.message_id=messages_tags.message_id)) INNER JOIN tags ON messages_tags.tag_id=tags.tag_id WHERE messages.user_id=? GROUP BY messages_tags.tag_id ORDER BY cnt DESC", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
- stmt.setInt(1, user.getUID());
- }
- rs = stmt.executeQuery();
- rs.last();
- tags = new com.juick.Tag[rs.getRow()];
- rs.beforeFirst();
- cnt = 0;
- while (rs.next()) {
- tags[cnt] = new com.juick.Tag();
- tags[cnt].Name = rs.getString(1);
- tags[cnt].UsageCnt = rs.getInt(2);
- if (tags[cnt].UsageCnt > maxUsageCnt) {
- maxUsageCnt = tags[cnt].UsageCnt;
- }
- cnt++;
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
- }
-
- if (tags != null && cnt > 0) {
- Arrays.sort(tags, 0, cnt);
- }
-
+ public static String pageUserTags(JdbcTemplate sql, com.juick.User user, com.juick.User visitor, int cnt) {
+ List<Tag> tags = TagQueries.getUserTagsAll(sql, user.getUID());
+ int maxUsageCnt = tags.stream().map(t -> t.UsageCnt).max(Integer::max).orElse(0);
String ret = "";
- for (int i = 0; i < cnt; i++) {
- String tag = Utils.encodeHTML(tags[i].Name);
+ int count = Math.min(tags.size(), cnt);
+ for (int i = 0; i < count; i++) {
+ String tag = Utils.encodeHTML(tags.get(i).Name);
try {
- tag = "<a href=\"./?tag=" + URLEncoder.encode(tags[i].Name, "UTF-8") + "\" title=\"" + tags[i].UsageCnt + "\" rel=\"nofollow\">" + tag + "</a>";
+ tag = "<a href=\"./?tag=" + URLEncoder.encode(tags.get(i).Name, "UTF-8") + "\" title=\""
+ + tags.get(i).UsageCnt + "\" rel=\"nofollow\">" + tag + "</a>";
} catch (UnsupportedEncodingException e) {
}
- if (tags[i].UsageCnt > maxUsageCnt / 3 * 2) {
+ if (tags.get(i).UsageCnt > maxUsageCnt / 3 * 2) {
ret += "<big>" + tag + "</big> ";
- } else if (tags[i].UsageCnt > maxUsageCnt / 3) {
+ } else if (tags.get(i).UsageCnt > maxUsageCnt / 3) {
ret += "<small>" + tag + "</small> ";
} else {
ret += tag + " ";
diff --git a/src/main/java/com/juick/http/www/UserThread.java b/src/main/java/com/juick/http/www/UserThread.java
index 4ee290ab..638e3a3b 100644
--- a/src/main/java/com/juick/http/www/UserThread.java
+++ b/src/main/java/com/juick/http/www/UserThread.java
@@ -21,9 +21,10 @@ import com.juick.Message;
import com.juick.Tag;
import com.juick.server.MessagesQueries;
import com.juick.server.UserQueries;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import java.io.IOException;
import java.io.PrintWriter;
-import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
@@ -36,7 +37,7 @@ import javax.servlet.http.HttpServletResponse;
*/
public class UserThread {
- protected void doGetThread(Connection sql, HttpServletRequest request, HttpServletResponse response, int MID) throws ServletException, IOException {
+ protected void doGetThread(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, int MID) throws ServletException, IOException {
com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
if (!MessagesQueries.canViewThread(sql, MID, visitor != null ? visitor.getUID() : 0)) {
@@ -98,7 +99,7 @@ public class UserThread {
}
}
- public static com.juick.Message printMessage(PrintWriter out, Connection sql, com.juick.Message msg, com.juick.User visitor) {
+ public static com.juick.Message printMessage(PrintWriter out, JdbcTemplate sql, com.juick.Message msg, com.juick.User visitor) {
msg.VisitorCanComment = visitor != null;
List<Tag> tags = MessagesQueries.getMessageTags(sql, msg.getMID());
@@ -128,7 +129,7 @@ public class UserThread {
out.println(" <div class=\"msg-cont\">");
out.println(" <div class=\"msg-menu\"><a href=\"#\" onclick=\"showMessageLinksDialog(" + msg.getMID() + "); return false\"></a></div>");
out.println(" <div class=\"msg-header\"><a href=\"/" + msg.getUser().getUName() + "/\">@" + msg.getUser().getUName() + "</a>:" + tagsStr + "</div>");
- out.println(" <div class=\"msg-ts\">" + PageTemplates.formatJSLocalTime(msg.TimestampString) + "</div>");
+ out.println(" <div class=\"msg-ts\">" + PageTemplates.formatJSLocalTime(msg.getDate()) + "</div>");
out.println(" <div class=\"msg-txt\">" + txt + "</div>");
if (msg.AttachmentType != null) {
@@ -189,7 +190,7 @@ public class UserThread {
return msg;
}
- public static void printReplies(PrintWriter out, Connection sql, com.juick.Message msg, com.juick.User visitor, boolean listview) {
+ public static void printReplies(PrintWriter out, JdbcTemplate sql, com.juick.Message msg, com.juick.User visitor, boolean listview) {
List<com.juick.Message> replies = MessagesQueries.getReplies(sql, msg.getMID());
List<Integer> blUIDs = new ArrayList<Integer>();
@@ -297,7 +298,7 @@ public class UserThread {
} else {
out.println(" <div class=\"msg-header\">[удалено]:</div>");
}
- out.println(" <div class=\"msg-ts\"><a href=\"/" + msg.getMID() + "#" + msg.getRID() + "\" title=\"" + msg.TimestampString + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.TimestampString) + "</a></div>");
+ out.println(" <div class=\"msg-ts\"><a href=\"/" + msg.getMID() + "#" + msg.getRID() + "\" title=\"" + PageTemplates.sdfSQL.format(msg.getDate()) + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.getDate()) + "</a></div>");
out.println(" <div class=\"msg-txt\">" + PageTemplates.formatMessage(msg.getText()) + "</div>");
if (msg.AttachmentType != null) {
out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\" alt=\"\"/></a></div>");
@@ -341,7 +342,7 @@ public class UserThread {
} else {
out.println(" <div class=\"msg-header\">[удалено]:</div>");
}
- out.println(" <div class=\"msg-ts\"><a href=\"/" + msg.getMID() + "#" + msg.getRID() + "\" title=\"" + msg.TimestampString + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.TimestampString) + "</a></div>");
+ out.println(" <div class=\"msg-ts\"><a href=\"/" + msg.getMID() + "#" + msg.getRID() + "\" title=\"" + PageTemplates.sdfSQL.format(msg.getDate()) + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.getDate()) + "</a></div>");
out.println(" <div class=\"msg-txt\">" + PageTemplates.formatMessage(msg.getText()) + "</div>");
if (msg.AttachmentType != null) {
out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\" alt=\"\"/></a></div>");
diff --git a/src/main/java/com/juick/http/www/Utils.java b/src/main/java/com/juick/http/www/Utils.java
index 931e2c21..ab721020 100644
--- a/src/main/java/com/juick/http/www/Utils.java
+++ b/src/main/java/com/juick/http/www/Utils.java
@@ -17,6 +17,8 @@
*/
package com.juick.http.www;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -77,7 +79,7 @@ public class Utils {
return attachmentFName;
}
- public static com.juick.User getVisitorUser(Connection sql, HttpServletRequest request, HttpServletResponse response) {
+ public static com.juick.User getVisitorUser(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) {
String hash = getCookie(request, "hash");
if (hash != null) {
com.juick.User visitor = com.juick.server.UserQueries.getUserByHash(sql, hash);
diff --git a/src/main/java/com/juick/http/www/VKontakteLogin.java b/src/main/java/com/juick/http/www/VKontakteLogin.java
index 5f26fef1..8fad3b7a 100644
--- a/src/main/java/com/juick/http/www/VKontakteLogin.java
+++ b/src/main/java/com/juick/http/www/VKontakteLogin.java
@@ -18,19 +18,18 @@
package com.juick.http.www;
import com.juick.server.UserQueries;
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.UUID;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.json.JSONException;
-import org.json.JSONObject;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.UUID;
/**
*
@@ -42,7 +41,7 @@ public class VKontakteLogin {
private static final String VK_SECRET = "z2afNI8jA5lIpZ2jsTm1";
private static final String VK_REDIRECT = "http://juick.com/_vklogin";
- protected void doGet(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String code = request.getParameter("code");
if (code == null || code.equals("")) {
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
@@ -114,42 +113,16 @@ public class VKontakteLogin {
}
}
- private int getUIDbyVKID(Connection sql, long vkID) {
- int uid = 0;
- PreparedStatement stmt = null;
- ResultSet rs = null;
+ private int getUIDbyVKID(JdbcTemplate sql, long vkID) {
try {
- stmt = sql.prepareStatement("SELECT user_id FROM vk WHERE vk_id=? AND user_id IS NOT NULL");
- stmt.setLong(1, vkID);
- rs = stmt.executeQuery();
- if (rs.first()) {
- uid = rs.getInt(1);
- }
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(rs, stmt);
+ return sql.queryForObject("SELECT user_id FROM vk WHERE vk_id=? AND user_id IS NOT NULL", Integer.class, vkID);
+ } catch (EmptyResultDataAccessException e) {
+ return 0;
}
- return uid;
}
- private boolean insertDB(Connection sql, long vkID, String loginhash, String token, String vkName, String vkLink) {
- boolean ret = false;
- PreparedStatement stmt = null;
- try {
- stmt = sql.prepareStatement("INSERT INTO vk(vk_id,loginhash,access_token,vk_name,vk_link) VALUES (?,?,?,?,?)");
- stmt.setLong(1, vkID);
- stmt.setString(2, loginhash);
- stmt.setString(3, token);
- stmt.setString(4, vkName);
- stmt.setString(5, vkLink);
- stmt.executeUpdate();
- ret = true;
- } catch (SQLException e) {
- System.err.println(e);
- } finally {
- Utils.finishSQL(null, stmt);
- }
- return ret;
+ private boolean insertDB(JdbcTemplate sql, long vkID, String loginhash, String token, String vkName, String vkLink) {
+ return sql.update("INSERT INTO vk(vk_id,loginhash,access_token,vk_name,vk_link) VALUES (?,?,?,?,?)",
+ vkID, loginhash, token, vkName, vkLink) > 0;
}
}
diff --git a/src/main/java/com/juick/server/protocol/JuickProtocol.java b/src/main/java/com/juick/server/protocol/JuickProtocol.java
new file mode 100644
index 00000000..1a2e5333
--- /dev/null
+++ b/src/main/java/com/juick/server/protocol/JuickProtocol.java
@@ -0,0 +1,375 @@
+package com.juick.server.protocol;
+
+import com.juick.*;
+import com.juick.json.MessageSerializer;
+import com.juick.server.*;
+import com.juick.server.protocol.annotation.UserCommand;
+import com.juick.xmpp.extensions.JuickMessage;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * Created by oxpa on 22.03.16.
+ */
+
+public class JuickProtocol {
+ MessageSerializer json = new MessageSerializer();
+ JdbcTemplate sql;
+ String baseUri;
+
+ public JuickProtocol(JdbcTemplate sql, String baseUri) {
+ this.sql = sql;
+ this.baseUri = baseUri;
+ }
+
+ /**
+ * find command by pattern and invoke
+ * @param user who send command
+ * @param userInput given by user
+ * @return command result
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ * @throws NoSuchMethodException
+ */
+ public ProtocolReply getReply(User user, String userInput) throws InvocationTargetException,
+ IllegalAccessException, NoSuchMethodException {
+ Optional<Method> cmd = Arrays.asList(getClass().getDeclaredMethods()).stream()
+ .filter(m -> m.isAnnotationPresent(UserCommand.class))
+ .filter(m -> Pattern.compile(m.getAnnotation(UserCommand.class).pattern(),
+ m.getAnnotation(UserCommand.class).patternFlags()).matcher(userInput).matches())
+ .findFirst();
+ if (!cmd.isPresent()) {
+ // default command - post as new message
+ return postMessage(user, userInput);
+ } else {
+ Matcher matcher = Pattern.compile(cmd.get().getAnnotation(UserCommand.class).pattern(),
+ cmd.get().getAnnotation(UserCommand.class).patternFlags()).matcher(userInput);
+ List<String> groups = new ArrayList<>();
+ while (matcher.find()) {
+ for (int i = 1; i <= matcher.groupCount(); i++) {
+ groups.add(matcher.group(i));
+ }
+ }
+ return (ProtocolReply) getClass().getMethod(cmd.get().getName(), User.class, String[].class)
+ .invoke(this, user, groups.toArray(new String[groups.size()]));
+ }
+ }
+
+ public ProtocolReply postMessage(User user, String input) {
+ List<Tag> tags = TagQueries.fromString(sql, input, false);
+ String body = input.substring(TagQueries.toString(tags).length());
+ int mid = MessagesQueries.createMessage(sql, user.getUID(), body, null, tags);
+ //app.events().publishEvent(new JuickMessageEvent(app.messages().getMessage(mid)));
+ return new ProtocolReply("New message posted.\n#" + mid + " " + baseUri + mid,
+ Optional.of(json.serializeList(Collections.singletonList(MessagesQueries.getMessage(sql, mid)))));
+ }
+
+ @UserCommand(pattern = "^#(\\++)$", help = "#+ - Show last Juick messages (#++ - second page, ...)")
+ public ProtocolReply commandLast(User user, String... arguments) {
+ // number of + is the page count
+ int page = arguments[0].length();
+ List<Integer> mids = MessagesQueries.getAll(sql, user.getUID(), page);
+ List<Message> messages = MessagesQueries.getMessages(sql, mids);
+ // TODO: message toString
+ return new ProtocolReply("Last messages: \n" + String.join("\n", messages.stream().map(Object::toString)
+ .collect(Collectors.toList())), Optional.of(json.serializeList(messages)));
+ }
+
+ @UserCommand(pattern = "^\\s*bl\\s*$", patternFlags = Pattern.CASE_INSENSITIVE,
+ help = "BL - Show your blacklist")
+ public ProtocolReply commandBL(User user_from, String... arguments) {
+ List<User> blusers;
+ List<String> bltags;
+
+ blusers = UserQueries.getUserBLUsers(sql, user_from.getUID());
+ bltags = TagQueries.getUserBLTags(sql, user_from.getUID());
+
+
+ String txt = "";
+ if (bltags.size() > 0) {
+ for (String bltag : bltags) {
+ txt += "*" + bltag + "\n";
+ }
+
+ if (blusers.size() > 0) {
+ txt += "\n";
+ }
+ }
+ if (blusers.size() > 0) {
+ for (User bluser : blusers) {
+ txt += "@" + bluser.getUName() + "\n";
+ }
+ }
+ if (txt.isEmpty()) {
+ txt = "You don't have any users or tags in your blacklist.";
+ }
+ return new ProtocolReply(txt, Optional.empty());
+ }
+
+ @UserCommand(pattern = "^\\@([^\\s\\n\\+]+)(\\+?)$",
+ help = "@username+ - Show user's info and last 10 messages (@username++ - second page, ..)")
+ public ProtocolReply commandUser(User user, String... arguments) {
+ User blogUser = UserQueries.getUserByName(sql, arguments[0]);
+ int page = arguments[1].length();
+ if (blogUser.getUID() > 0) {
+ List<Integer> mids = MessagesQueries.getUserBlog(sql, blogUser.getUID(), 0, page);
+ List<Message> messages = MessagesQueries.getMessages(sql, mids);
+ return new ProtocolReply(String.format("Last messages from @%s:\n%s", arguments[0],
+ String.join("\n", messages.stream()
+ .map(Object::toString).collect(Collectors.toList()))),
+ Optional.of(json.serializeList(messages)));
+ }
+ return new ProtocolReply("User not found", Optional.empty());
+ }
+
+ @UserCommand(pattern = "^\\s*d\\s*\\#([0-9]+)\\s*$", patternFlags = Pattern.CASE_INSENSITIVE,
+ help = "D #12345 - delete the message")
+ public ProtocolReply commandDel(User user, String... args) {
+ try {
+ int mid = Integer.parseInt(args[0]);
+ if (MessagesQueries.deleteMessage(sql, user.getUID(), mid)) {
+ return new ProtocolReply(String.format("Message %s deleted", mid), Optional.empty());
+ }
+ } catch (NumberFormatException e) {
+ return new ProtocolReply("Error", Optional.empty());
+ }
+ return new ProtocolReply("Error", Optional.empty());
+ }
+
+ @UserCommand(pattern = "^\\s*login\\s*$", patternFlags = Pattern.CASE_INSENSITIVE,
+ help = "LOGIN - log in to Juick website")
+ public ProtocolReply commandLogin(User user, String... arguments) {
+ return new ProtocolReply(baseUri + "?" + UserQueries.getHashByUID(sql, user.getUID()),
+ Optional.empty());
+ }
+
+ @UserCommand(pattern = "^(#+)$", help = "# - Show last messages from your feed (## - second page, ...)")
+ public ProtocolReply commandMyFeed(User user, String... arguments) {
+ // number of # is the page count
+ int page = arguments[0].length();
+ List<Integer> mids = MessagesQueries.getMyFeed(sql, user.getUID(), page);
+ List<Message> messages = MessagesQueries.getMessages(sql, mids);
+ // TODO: add instructions for empty feed
+ return new ProtocolReply("Your feed: \n" + String.join("\n",
+ messages.stream().map(Object::toString).collect(Collectors.toList())),
+ Optional.of(json.serializeList(messages)));
+ }
+
+ @UserCommand(pattern = "^\\s*(on|off)\\s*$", patternFlags = Pattern.CASE_INSENSITIVE,
+ help = "ON/OFF - Enable/disable subscriptions delivery")
+ public ProtocolReply commandOnOff(User user, String[] input) {
+ UserQueries.ActiveStatus newStatus;
+ String retValUpdated;
+ if (input[0].toLowerCase().equals("on")) {
+ newStatus = UserQueries.ActiveStatus.Active;
+ retValUpdated = "Notifications are activated for " + user.getJID();
+ } else {
+ newStatus = UserQueries.ActiveStatus.Inactive;
+ retValUpdated = "Notifications are disabled for " + user.getJID();
+ }
+
+ if (UserQueries.setActiveStatusForJID(sql, user.getJID(), newStatus)) {
+ return new ProtocolReply(retValUpdated, Optional.empty());
+ } else {
+ return new ProtocolReply(String.format("Subscriptions status for %s was not changed", user.getJID()),
+ Optional.empty());
+ }
+ }
+
+ @UserCommand(pattern = "^\\s*ping\\s*$", patternFlags = Pattern.CASE_INSENSITIVE,
+ help = "PING - returns you a PONG")
+ public ProtocolReply commandPing(User user, String[] input) {
+ return new ProtocolReply("PONG", Optional.empty());
+ }
+
+ @UserCommand(pattern = "^\\@(\\S+)\\s+([\\s\\S]+)$", help = "@username message - send PM to username")
+ public ProtocolReply commandPM(User user_from, String... arguments) {
+ String user_to = arguments[0];
+ String body = arguments[1];
+ int ret = 0;
+
+ int uid_to = 0;
+ String jid_to = null;
+ boolean haveInRoster = false;
+
+ if (user_to.indexOf('@') > 0) {
+ uid_to = UserQueries.getUIDbyJID(sql, user_to);
+ } else {
+ uid_to = UserQueries.getUIDbyName(sql, user_to);
+ }
+
+ if (uid_to > 0) {
+ if (!UserQueries.isInBLAny(sql, uid_to, user_from.getUID())) {
+ if (PMQueries.createPM(sql, user_from.getUID(), uid_to, body)) {
+ //jid_to = UserQueries.getJIDsbyUID(sql, uid_to);
+ if (jid_to != null) {
+ haveInRoster = PMQueries.havePMinRoster(sql, user_from.getUID(), jid_to);
+ }
+ ret = 200;
+ } else {
+ ret = 500;
+ }
+ } else {
+ ret = 403;
+ }
+ } else {
+ ret = 404;
+ }
+
+
+ if (ret == 200) {
+ JuickMessage jmsg = new JuickMessage();
+ jmsg.setUser(user_from);
+ jmsg.setText(body);
+ // TODO: add PM payload
+ //app.events().publishEvent(new JuickMessageEvent(jmsg));
+ /* TODO: move to XMPP component
+ if (jid_to != null) {
+ Message mm = new Message();
+ mm.to = new JID(jid_to);
+ mm.type = Message.Type.chat;
+ if (haveInRoster) {
+ mm.from = new JID(user_from.getUName(), getDomain(), "Juick");
+ mm.body = body;
+ } else {
+ mm.from = new JID("juick", getDomain(), "Juick");
+ mm.body = "Private message from @" + user_from.getUName() + ":\n" + body;
+ }
+ return Collections.singletonList(mm);
+ }
+ */
+ }
+ if (ret == 200) {
+ return new ProtocolReply("Private message sent", Optional.empty());
+ } else {
+ return new ProtocolReply("Error " + ret, Optional.empty());
+ }
+ }
+
+ @UserCommand(pattern = "^#(\\d+)(\\+?)$", help = "#1234 - Show message (#1234+ - message with replies)")
+ public ProtocolReply commandShow(User user, String... arguments) {
+ boolean showReplies = arguments[1].length() > 0;
+ int mid;
+ try {
+ mid = Integer.parseInt(arguments[0]);
+ } catch (NumberFormatException e) {
+ return new ProtocolReply("Error", Optional.empty());
+ }
+ Message msg = MessagesQueries.getMessage(sql, mid);
+ if (showReplies) {
+ List<Message> replies = MessagesQueries.getReplies(sql, mid);
+ replies.add(0, msg);
+ return new ProtocolReply(String.join("\n",
+ replies.stream().map(Object::toString).collect(Collectors.toList())),
+ Optional.of(json.serializeList(replies)));
+ }
+ return new ProtocolReply(msg.toString(), Optional.of(json.serializeList(Collections.singletonList(msg))));
+ }
+ @UserCommand(pattern = "^(#|\\.)(\\d+)((\\.|\\-|\\/)(\\d+))?\\s([\\s\\S]+)",
+ help = "#1234 *tag *tag2 - edit tags\n#1234 text - reply to message")
+ public ProtocolReply EditOrReply(User user, String... args) {
+ int mid;
+ try {
+ mid = Integer.parseInt(args[1]);
+ } catch (NumberFormatException e) {
+ return new ProtocolReply("Error", Optional.empty());
+ }
+ int rid;
+ try {
+ rid = Integer.parseInt(args[4]);
+ } catch (NumberFormatException e) {
+ rid = 0;
+ }
+ String txt = args[5];
+ List<Tag> messageTags = TagQueries.fromString(sql, txt, true);
+ if (messageTags.size() > 0) {
+ if (user.getUID() != MessagesQueries.getMessageAuthor(sql, mid).getUID()) {
+ return new ProtocolReply("It is not your message", Optional.empty());
+ }
+ TagQueries.updateTags(sql, mid, messageTags);
+ return new ProtocolReply("Tags are updated", Optional.empty());
+ } else {
+ int newrid = MessagesQueries.createReply(sql, mid, rid, user.getUID(), txt, null);
+ return new ProtocolReply("Reply posted.\n#" + mid + "/" + newrid + " "
+ + baseUri + mid + "/" + newrid,
+ Optional.of(json.serializeList(Collections.singletonList(MessagesQueries.getReply(sql, mid, newrid)))));
+ }
+ }
+
+ @UserCommand(pattern = "^(s|u)\\s+#(\\d+)$", help = "S #1234 - subscribe to comments",
+ patternFlags = Pattern.CASE_INSENSITIVE)
+ public ProtocolReply commandSubscribeMessage(User user, String... args) {
+ boolean subscribe = args[0].equalsIgnoreCase("s");
+ int mid;
+ try {
+ mid = Integer.parseInt(args[1]);
+ } catch (NumberFormatException e) {
+ return new ProtocolReply("Error", Optional.empty());
+ }
+ if (subscribe) {
+ if (SubscriptionsQueries.subscribeMessage(sql, mid, user.getUID())) {
+ return new ProtocolReply("Subscribed", Optional.empty());
+ }
+ } else {
+ if (SubscriptionsQueries.unSubscribeMessage(sql, mid, user.getUID())) {
+ return new ProtocolReply("Unsubscribed from #" + mid, Optional.empty());
+ }
+ return new ProtocolReply("You was not subscribed to #" + mid, Optional.empty());
+ }
+ return new ProtocolReply("Error", Optional.empty());
+ }
+ @UserCommand(pattern = "^(s|u)\\s+\\@(\\S+)$", help = "S @user - subscribe to user's posts",
+ patternFlags = Pattern.CASE_INSENSITIVE)
+ public ProtocolReply commandSubscribeUser(User user, String... args) {
+ boolean subscribe = args[0].equalsIgnoreCase("s");
+ User toUser = UserQueries.getUserByName(sql, args[1]);
+ if (toUser.getUID() > 0) {
+ if (subscribe) {
+ if (SubscriptionsQueries.subscribeUser(sql, user, toUser)) {
+ return new ProtocolReply("Subscribed", Optional.empty());
+ // TODO: notification
+ // TODO: already subscribed case
+ }
+ } else {
+ if (SubscriptionsQueries.unSubscribeUser(sql, user, toUser)) {
+ return new ProtocolReply("Unsubscribed from @" + toUser.getUName(), Optional.empty());
+ }
+ return new ProtocolReply("You was not subscribed to @" + toUser.getUName(), Optional.empty());
+ }
+ }
+ return new ProtocolReply("Error", Optional.empty());
+ }
+ @UserCommand(pattern = "^(s|u)\\s+\\*(\\S+)$", help = "S *tag - subscribe to tag" +
+ "\nU *tag - unsubscribe from tag", patternFlags = Pattern.CASE_INSENSITIVE)
+ public ProtocolReply commandSubscribeTag(User user, String... args) {
+ boolean subscribe = args[0].equalsIgnoreCase("s");
+ Tag tag = TagQueries.getTag(sql, args[1], true);
+ if (subscribe) {
+ if (SubscriptionsQueries.subscribeTag(sql, user, tag)) {
+ return new ProtocolReply("Subscribed", Optional.empty());
+ }
+ } else {
+ if (SubscriptionsQueries.unSubscribeTag(sql, user, tag)) {
+ return new ProtocolReply("Unsubscribed from " + tag.Name, Optional.empty());
+ }
+ return new ProtocolReply("You was not subscribed to " + tag.Name, Optional.empty());
+ }
+ return new ProtocolReply("Error", Optional.empty());
+ }
+
+ @UserCommand(pattern = "^\\s*help\\s*$", patternFlags = Pattern.CASE_INSENSITIVE,
+ help = "HELP - returns this help message")
+ public ProtocolReply commandHelp(User user, String[] input) {
+ List<String> commandsHelp = Arrays.asList(getClass().getDeclaredMethods()).stream()
+ .filter(m -> m.isAnnotationPresent(UserCommand.class))
+ .map(m -> m.getAnnotation(UserCommand.class).help())
+ .collect(Collectors.toList());
+ return new ProtocolReply(String.join("\n", commandsHelp), Optional.empty());
+ }
+}
diff --git a/src/main/java/com/juick/server/protocol/ProtocolReply.java b/src/main/java/com/juick/server/protocol/ProtocolReply.java
new file mode 100644
index 00000000..d9d36a5d
--- /dev/null
+++ b/src/main/java/com/juick/server/protocol/ProtocolReply.java
@@ -0,0 +1,23 @@
+package com.juick.server.protocol;
+
+import java.util.Optional;
+
+/**
+ * Created by vitalyster on 08.04.2016.
+ */
+public class ProtocolReply {
+
+ private Optional<String> json;
+ private String description;
+
+ public ProtocolReply(String text, Optional<String> json) {
+ this.description = text;
+ this.json = json;
+ }
+ public String getDescription() {
+ return description;
+ }
+ public Optional<String> getJson() {
+ return json;
+ }
+}
diff --git a/src/main/java/com/juick/server/protocol/annotation/UserCommand.java b/src/main/java/com/juick/server/protocol/annotation/UserCommand.java
new file mode 100644
index 00000000..af7c4924
--- /dev/null
+++ b/src/main/java/com/juick/server/protocol/annotation/UserCommand.java
@@ -0,0 +1,31 @@
+package com.juick.server.protocol.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by oxpa on 22.03.16.
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UserCommand {
+ /**
+ *
+ * @return a command pattern
+ */
+ String pattern() default "";
+
+ /**
+ *
+ * @return pattern flags
+ */
+ int patternFlags() default 0;
+
+ /**
+ *
+ * @return a string used in HELP command output. Basically, only 1 string
+ */
+ String help() default "";
+}
diff --git a/src/main/java/com/juick/xmpp/extensions/JuickMessage.java b/src/main/java/com/juick/xmpp/extensions/JuickMessage.java
index 53dd6deb..885b2375 100644
--- a/src/main/java/com/juick/xmpp/extensions/JuickMessage.java
+++ b/src/main/java/com/juick/xmpp/extensions/JuickMessage.java
@@ -20,6 +20,10 @@ package com.juick.xmpp.extensions;
import com.juick.xmpp.utils.XmlUtils;
import com.juick.xmpp.*;
import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -31,12 +35,17 @@ public class JuickMessage extends com.juick.Message implements StanzaChild {
public final static String XMLNS = "http://juick.com/message";
public final static String TagName = "juick";
+ private SimpleDateFormat df;
public JuickMessage() {
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ df.setTimeZone(TimeZone.getTimeZone("UTC"));
}
public JuickMessage(com.juick.Message msg) {
super(msg);
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ df.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@Override
@@ -45,7 +54,7 @@ public class JuickMessage extends com.juick.Message implements StanzaChild {
}
@Override
- public JuickMessage parse(XmlPullParser parser) throws XmlPullParserException, IOException {
+ public JuickMessage parse(XmlPullParser parser) throws XmlPullParserException, IOException, ParseException {
JuickMessage jmsg = new JuickMessage();
final String sMID = parser.getAttributeValue(null, "mid");
@@ -72,7 +81,10 @@ public class JuickMessage extends com.juick.Message implements StanzaChild {
if (sReadOnly != null) {
jmsg.ReadOnly = true;
}
- jmsg.TimestampString = parser.getAttributeValue(null, "ts");
+ String ts = parser.getAttributeValue(null, "timestamp");
+ if (ts != null) {
+ jmsg.setDate(df.parse(ts));
+ }
jmsg.AttachmentType = parser.getAttributeValue(null, "attach");
while (parser.next() == XmlPullParser.START_TAG) {
@@ -112,8 +124,8 @@ public class JuickMessage extends com.juick.Message implements StanzaChild {
if (ReadOnly) {
ret += " readonly=\"1\"";
}
- if (TimestampString != null) {
- ret += " ts=\"" + TimestampString + "\"";
+ if (getDate() != null) {
+ ret += " ts=\"" + df.format(getDate()) + "\"";
}
if (AttachmentType != null) {
ret += " attach=\"" + AttachmentType + "\"";
diff --git a/src/main/java/com/juick/xmpp/s2s/CleaningUp.java b/src/main/java/com/juick/xmpp/s2s/CleaningUp.java
index 48771580..14d97ed8 100644
--- a/src/main/java/com/juick/xmpp/s2s/CleaningUp.java
+++ b/src/main/java/com/juick/xmpp/s2s/CleaningUp.java
@@ -10,19 +10,24 @@ import java.util.Iterator;
* @author ugnich
*/
public class CleaningUp implements Runnable {
+ XMPPComponent xmpp;
+
+ public CleaningUp(XMPPComponent xmpp) {
+ this.xmpp = xmpp;
+ }
@Override
public void run() {
while (true) {
try {
- PrintWriter statsFile = new PrintWriter(XMPPComponent.STATSFILE, "UTF-8");
+ PrintWriter statsFile = new PrintWriter(xmpp.STATSFILE, "UTF-8");
statsFile.write("<html><body><h2>Threads: " + Thread.activeCount() + "</h2>");
- statsFile.write("<h2>Out (" + XMPPComponent.outConnections.size() + ")</h2><table border=1><tr><th>to</th><th>sid</th><th>inactive</th><th>out packets</th><th>out bytes</th></tr>");
+ statsFile.write("<h2>Out (" + xmpp.outConnections.size() + ")</h2><table border=1><tr><th>to</th><th>sid</th><th>inactive</th><th>out packets</th><th>out bytes</th></tr>");
long now = System.currentTimeMillis();
- synchronized (XMPPComponent.outConnections) {
- for (Iterator<ConnectionOut> i = XMPPComponent.outConnections.iterator(); i.hasNext();) {
+ synchronized (xmpp.outConnections) {
+ for (Iterator<ConnectionOut> i = xmpp.outConnections.iterator(); i.hasNext();) {
ConnectionOut c = i.next();
int inactive = (int) ((double) (now - c.tsLocalData) / 1000.0);
if (inactive > 900) {
@@ -40,10 +45,10 @@ public class CleaningUp implements Runnable {
}
}
- statsFile.write("</table><h2>In (" + XMPPComponent.inConnections.size() + ")</h2><table border=1><tr><th>from</th><th>sid</th><th>inactive</th><th>in packets</th></tr>");
+ statsFile.write("</table><h2>In (" + xmpp.inConnections.size() + ")</h2><table border=1><tr><th>from</th><th>sid</th><th>inactive</th><th>in packets</th></tr>");
- synchronized (XMPPComponent.inConnections) {
- for (Iterator<ConnectionIn> i = XMPPComponent.inConnections.iterator(); i.hasNext();) {
+ synchronized (xmpp.inConnections) {
+ for (Iterator<ConnectionIn> i = xmpp.inConnections.iterator(); i.hasNext();) {
ConnectionIn c = i.next();
int inactive = (int) ((double) (now - c.tsRemoteData) / 1000.0);
if (inactive > 900) {
@@ -73,10 +78,10 @@ public class CleaningUp implements Runnable {
}
}
- statsFile.write("</table><h2>Cache (" + XMPPComponent.outCache.size() + ")</h2><table border=1><tr><th>host</th><th>live</th><th>size</th></tr>");
+ statsFile.write("</table><h2>Cache (" + xmpp.outCache.size() + ")</h2><table border=1><tr><th>host</th><th>live</th><th>size</th></tr>");
- synchronized (XMPPComponent.outCache) {
- for (Iterator<CacheEntry> i = XMPPComponent.outCache.iterator(); i.hasNext();) {
+ synchronized (xmpp.outCache) {
+ for (Iterator<CacheEntry> i = xmpp.outCache.iterator(); i.hasNext();) {
CacheEntry c = i.next();
int inactive = (int) ((double) (now - c.tsCreated) / 1000.0);
if (inactive > 600) {
diff --git a/src/main/java/com/juick/xmpp/s2s/Connection.java b/src/main/java/com/juick/xmpp/s2s/Connection.java
index c1bbf22e..eae6efaa 100644
--- a/src/main/java/com/juick/xmpp/s2s/Connection.java
+++ b/src/main/java/com/juick/xmpp/s2s/Connection.java
@@ -30,6 +30,7 @@ public class Connection {
public long tsLocalData = 0;
public long bytesLocal = 0;
public long packetsLocal = 0;
+ XMPPComponent xmpp;
Socket socket;
public static final String NS_DB = "jabber:server:dialback";
public static final String NS_TLS = "urn:ietf:params:xml:ns:xmpp-tls";
@@ -52,17 +53,18 @@ public class Connection {
};
- public Connection() throws XmlPullParserException, KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, KeyManagementException {
+ public Connection(XMPPComponent xmpp) throws XmlPullParserException, KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, KeyManagementException {
+ this.xmpp = xmpp;
tsCreated = System.currentTimeMillis();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
KeyStore ks = KeyStore.getInstance("JKS");
- try (InputStream ksIs = new FileInputStream(XMPPComponent.keystore)) {
- ks.load(ksIs, XMPPComponent.keystorePassword.toCharArray());
+ try (InputStream ksIs = new FileInputStream(xmpp.keystore)) {
+ ks.load(ksIs, xmpp.keystorePassword.toCharArray());
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
- kmf.init(ks, XMPPComponent.keystorePassword.toCharArray());
+ kmf.init(ks, xmpp.keystorePassword.toCharArray());
sc = SSLContext.getInstance("TLSv1.2");
sc.init(kmf.getKeyManagers(), trustAllCerts, new SecureRandom());
diff --git a/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java b/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java
index 93e761a0..345caea9 100644
--- a/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java
+++ b/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java
@@ -31,9 +31,11 @@ public class ConnectionIn extends Connection implements Runnable {
final public List<String> from = new ArrayList<>();
public long tsRemoteData = 0;
public long packetsRemote = 0;
+ JuickBot bot;
- public ConnectionIn(Socket socket) throws Exception {
- super();
+ public ConnectionIn(XMPPComponent xmpp, JuickBot bot, Socket socket) throws Exception {
+ super(xmpp);
+ this.bot = bot;
this.socket = socket;
streamID = UUID.randomUUID().toString();
restartParser();
@@ -69,19 +71,19 @@ public class ConnectionIn extends Connection implements Runnable {
String dfrom = parser.getAttributeValue(null, "from");
String to = parser.getAttributeValue(null, "to");
LOGGER.info("STREAM FROM " + dfrom + " TO " + to + " " + streamID + " ASKING FOR DIALBACK");
- if (dfrom.endsWith(XMPPComponent.HOSTNAME) && (dfrom.equals(XMPPComponent.HOSTNAME) || dfrom.endsWith("." + XMPPComponent.HOSTNAME))) {
+ if (dfrom.endsWith(xmpp.HOSTNAME) && (dfrom.equals(xmpp.HOSTNAME) || dfrom.endsWith("." + xmpp.HOSTNAME))) {
break;
}
- if (to != null && to.equals(XMPPComponent.HOSTNAME)) {
+ if (to != null && to.equals(xmpp.HOSTNAME)) {
String dbKey = XmlUtils.getTagText(parser);
updateTsRemoteData();
- ConnectionOut c = XMPPComponent.getConnectionOut(dfrom, false);
+ ConnectionOut c = xmpp.getConnectionOut(dfrom, false);
if (c != null) {
c.sendDialbackVerify(streamID, dbKey);
} else {
- c = new ConnectionOut(dfrom, streamID, dbKey);
- XMPPComponent.executorService.submit(c);
+ c = new ConnectionOut(xmpp, dfrom, streamID, dbKey);
+ xmpp.executorService.submit(c);
}
} else {
throw new HostUnknownException("STREAM FROM " + dfrom + " " + streamID + " INVALID TO " + to);
@@ -107,15 +109,15 @@ public class ConnectionIn extends Connection implements Runnable {
} else if (tag.equals("presence") && checkFromTo(parser)) {
Presence p = Presence.parse(parser, null);
if (p != null && (p.type == null || !p.type.equals(Presence.Type.error))) {
- JuickBot.incomingPresence(p);
+ bot.incomingPresence(p);
}
} else if (tag.equals("message") && checkFromTo(parser)) {
updateTsRemoteData();
- Message msg = Message.parse(parser, XMPPComponent.childParsers);
+ Message msg = Message.parse(parser, xmpp.childParsers);
if (msg != null && (msg.type == null || !msg.type.equals(Message.Type.error))) {
LOGGER.info("STREAM " + streamID + ": " + msg.toString());
- if (!JuickBot.incomingMessage(msg)) {
- XMPPComponent.connRouter.router.send(msg.toString());
+ if (!bot.incomingMessage(msg)) {
+ xmpp.router.send(msg.toString());
}
}
} else if (tag.equals("iq") && checkFromTo(parser)) {
@@ -124,7 +126,7 @@ public class ConnectionIn extends Connection implements Runnable {
String xml = XmlUtils.parseToString(parser, true);
if (type == null || !type.equals(Iq.Type.error)) {
LOGGER.info("STREAM " + streamID + ": " + xml);
- XMPPComponent.connRouter.router.send(xml);
+ xmpp.router.send(xml);
}
} else if (!isSecured() && tag.equals("starttls")) {
LOGGER.info("STREAM " + streamID + " SECURING");
@@ -140,7 +142,7 @@ public class ConnectionIn extends Connection implements Runnable {
} catch (SSLException sex) {
LOGGER.warning("STREAM " + streamID + " SSL ERROR");
sendStanza("<failed xmlns\"" + NS_TLS + "\" />");
- XMPPComponent.removeConnectionIn(this);
+ xmpp.removeConnectionIn(this);
closeConnection();
}
} else if (isSecured() && tag.equals("stream") && parser.getNamespace().equals(NS_STREAM)) {
@@ -150,17 +152,17 @@ public class ConnectionIn extends Connection implements Runnable {
}
}
LOGGER.warning("STREAM " + streamID + " FINISHED");
- XMPPComponent.removeConnectionIn(this);
+ xmpp.removeConnectionIn(this);
closeConnection();
} catch (EOFException ex) {
LOGGER.info(String.format("STREAM %s CLOSED (dirty)", streamID));
- XMPPComponent.removeConnectionIn(this);
+ xmpp.removeConnectionIn(this);
closeConnection();
} catch (HostUnknownException e) {
LOGGER.warning(e.getMessage());
} catch (Exception e) {
LOGGER.log(Level.WARNING, "STREAM " + streamID + " ERROR", e);
- XMPPComponent.removeConnectionIn(this);
+ xmpp.removeConnectionIn(this);
closeConnection();
}
}
@@ -172,10 +174,10 @@ public class ConnectionIn extends Connection implements Runnable {
void sendOpenStream(String from, boolean xmppversionnew) throws IOException {
String openStream = "<?xml version='1.0'?><stream:stream xmlns='jabber:server' " +
"xmlns:stream='http://etherx.jabber.org/streams' xmlns:db='jabber:server:dialback' from='" +
- XMPPComponent.HOSTNAME + "' id='" + streamID + "' version='1.0'>";
+ xmpp.HOSTNAME + "' id='" + streamID + "' version='1.0'>";
if (xmppversionnew) {
openStream += "<stream:features>";
- if (!isSecured() && !XMPPComponent.brokenSSLhosts.contains(from)) {
+ if (!isSecured() && !xmpp.brokenSSLhosts.contains(from)) {
openStream += "<starttls xmlns=\"" + NS_TLS + "\"><optional/></starttls>";
}
openStream += "</stream:features>";
@@ -185,7 +187,7 @@ public class ConnectionIn extends Connection implements Runnable {
public void sendDialbackResult(String sfrom, String type) {
try {
- sendStanza("<db:result from='" + XMPPComponent.HOSTNAME + "' to='" + sfrom + "' type='" + type + "'/>");
+ sendStanza("<db:result from='" + xmpp.HOSTNAME + "' to='" + sfrom + "' type='" + type + "'/>");
if (type.equals("valid")) {
from.add(sfrom);
LOGGER.info("STREAM FROM " + sfrom + " " + streamID + " READY");
@@ -200,7 +202,7 @@ public class ConnectionIn extends Connection implements Runnable {
String cto = parser.getAttributeValue(null, "to");
if (cfrom != null && cto != null && !cfrom.isEmpty() && !cto.isEmpty()) {
JID jidto = new JID(cto);
- if (jidto.Host != null && jidto.Username != null && jidto.Host.equals(XMPPComponent.HOSTNAME) && jidto.Username.matches("^[a-zA-Z0-9\\-]{2,16}$")) {
+ if (jidto.Host != null && jidto.Username != null && jidto.Host.equals(xmpp.HOSTNAME) && jidto.Username.matches("^[a-zA-Z0-9\\-]{2,16}$")) {
JID jidfrom = new JID(cfrom);
int size = from.size();
for (int i = 0; i < size; i++) {
diff --git a/src/main/java/com/juick/xmpp/s2s/ConnectionListener.java b/src/main/java/com/juick/xmpp/s2s/ConnectionListener.java
deleted file mode 100644
index 569d3db0..00000000
--- a/src/main/java/com/juick/xmpp/s2s/ConnectionListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.juick.xmpp.s2s;
-
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author vt
- */
-public class ConnectionListener implements Runnable {
-
- private static final Logger logger = Logger.getLogger(ConnectionListener.class.getName());
-
- @Override
- public void run() {
- try {
- final ServerSocket listener = new ServerSocket(5269);
- logger.info("s2s listener ready");
- while (true) {
- try {
- Socket socket = listener.accept();
- ConnectionIn client = new ConnectionIn(socket);
- XMPPComponent.addConnectionIn(client);
- XMPPComponent.executorService.submit(client);
- } catch (Exception e) {
- logger.log(Level.SEVERE, "s2s error", e);
- }
- }
- } catch (Exception e) {
- logger.log(Level.SEVERE, "s2s listener exception", e);
- }
- }
-}
diff --git a/src/main/java/com/juick/xmpp/s2s/ConnectionOut.java b/src/main/java/com/juick/xmpp/s2s/ConnectionOut.java
index d3a10406..fede701e 100644
--- a/src/main/java/com/juick/xmpp/s2s/ConnectionOut.java
+++ b/src/main/java/com/juick/xmpp/s2s/ConnectionOut.java
@@ -17,6 +17,7 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
+import java.util.UUID;
import java.util.logging.Level;
/**
@@ -29,30 +30,31 @@ public class ConnectionOut extends Connection implements Runnable {
String checkSID = null;
String dbKey = null;
- public ConnectionOut(String hostname) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, XmlPullParserException, KeyManagementException, KeyStoreException, IOException {
- super();
+ public ConnectionOut(XMPPComponent xmpp, String hostname) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, XmlPullParserException, KeyManagementException, KeyStoreException, IOException {
+ super(xmpp);
to = hostname;
}
- public ConnectionOut(String hostname, String checkSID, String dbKey) throws Exception {
- super();
+ public ConnectionOut(XMPPComponent xmpp, String hostname, String checkSID, String dbKey) throws Exception {
+ super(xmpp);
to = hostname;
this.checkSID = checkSID;
this.dbKey = dbKey;
+ streamID = UUID.randomUUID().toString();
}
void sendOpenStream() throws IOException {
sendStanza("<?xml version='1.0'?><stream:stream xmlns='jabber:server' id='" + streamID +
"' xmlns:stream='http://etherx.jabber.org/streams' xmlns:db='jabber:server:dialback' from='" +
- XMPPComponent.HOSTNAME + "' to='" + to + "' version='1.0'>");
+ xmpp.HOSTNAME + "' to='" + to + "' version='1.0'>");
}
void processDialback() throws Exception {
if (checkSID != null) {
sendDialbackVerify(checkSID, dbKey);
}
- sendStanza("<db:result from='" + XMPPComponent.HOSTNAME + "' to='" + to + "'>" +
- generateDialbackKey(to, XMPPComponent.HOSTNAME, streamID) + "</db:result>");
+ sendStanza("<db:result from='" + xmpp.HOSTNAME + "' to='" + to + "'>" +
+ generateDialbackKey(to, xmpp.HOSTNAME, streamID) + "</db:result>");
}
@Override
@@ -76,7 +78,7 @@ public class ConnectionOut extends Connection implements Runnable {
}
LOGGER.info("STREAM TO " + to + " " + streamID + " OPEN");
- XMPPComponent.addConnectionOut(ConnectionOut.this);
+ xmpp.addConnectionOut(ConnectionOut.this);
boolean xmppversionnew = parser.getAttributeValue(null, "version") != null;
if (!xmppversionnew) {
processDialback();
@@ -95,7 +97,7 @@ public class ConnectionOut extends Connection implements Runnable {
streamReady = true;
LOGGER.info("STREAM TO " + to + " " + streamID + " READY");
- String cache = XMPPComponent.getFromCache(to);
+ String cache = xmpp.getFromCache(to);
if (cache != null) {
LOGGER.info("STREAM TO " + to + " " + streamID + " SENDING CACHE");
sendStanza(cache);
@@ -110,7 +112,7 @@ public class ConnectionOut extends Connection implements Runnable {
String type = parser.getAttributeValue(null, "type");
String sid = parser.getAttributeValue(null, "id");
if (from != null && from.equals(to) && sid != null && !sid.isEmpty() && type != null) {
- ConnectionIn c = XMPPComponent.getConnectionIn(sid);
+ ConnectionIn c = xmpp.getConnectionIn(sid);
if (c != null) {
c.sendDialbackResult(from, type);
}
@@ -118,7 +120,7 @@ public class ConnectionOut extends Connection implements Runnable {
XmlUtils.skip(parser);
} else if (tag.equals("features") && parser.getNamespace().equals(NS_STREAM)) {
StreamFeatures features = StreamFeatures.parse(parser);
- if (!isSecured() && features.STARTTLS >= 0 && !XMPPComponent.brokenSSLhosts.contains(to)) {
+ if (!isSecured() && features.STARTTLS >= 0 && !xmpp.brokenSSLhosts.contains(to)) {
System.out.println("STREAM TO " + to + " " + streamID + " SECURING");
sendStanza("<starttls xmlns=\"" + NS_TLS + "\" />");
} else {
@@ -136,7 +138,7 @@ public class ConnectionOut extends Connection implements Runnable {
} catch (SSLException sex) {
LOGGER.log(Level.SEVERE, String.format("s2s ssl error: %s %s", to, streamID), sex);
sendStanza("<failed xmlns\"" + NS_TLS + "\" />");
- XMPPComponent.removeConnectionOut(this);
+ xmpp.removeConnectionOut(this);
closeConnection();
}
} else if (isSecured() && tag.equals("stream") && parser.getNamespace().equals(NS_STREAM)) {
@@ -147,22 +149,22 @@ public class ConnectionOut extends Connection implements Runnable {
}
LOGGER.warning("STREAM TO " + to + " " + streamID + " FINISHED");
- XMPPComponent.removeConnectionOut(ConnectionOut.this);
+ xmpp.removeConnectionOut(ConnectionOut.this);
closeConnection();
} catch (EOFException eofex) {
LOGGER.info(String.format("STREAM %s %s CLOSED (dirty)", to, streamID));
- XMPPComponent.removeConnectionOut(ConnectionOut.this);
+ xmpp.removeConnectionOut(ConnectionOut.this);
closeConnection();
} catch (Exception e) {
LOGGER.log(Level.SEVERE, String.format("s2s out exception: %s %s", to, streamID), e);
- XMPPComponent.removeConnectionOut(ConnectionOut.this);
+ xmpp.removeConnectionOut(ConnectionOut.this);
closeConnection();
}
}
public void sendDialbackVerify(String sid, String key) {
try {
- sendStanza("<db:verify from='" + XMPPComponent.HOSTNAME + "' to='" + to + "' id='" + sid + "'>" + key + "</db:verify>");
+ sendStanza("<db:verify from='" + xmpp.HOSTNAME + "' to='" + to + "' id='" + sid + "'>" + key + "</db:verify>");
} catch (IOException e) {
LOGGER.log(Level.WARNING, "STREAM TO " + to + " " + streamID + " ERROR", e);
}
diff --git a/src/main/java/com/juick/xmpp/s2s/JuickBot.java b/src/main/java/com/juick/xmpp/s2s/JuickBot.java
index 25c75dfe..f0b71689 100644
--- a/src/main/java/com/juick/xmpp/s2s/JuickBot.java
+++ b/src/main/java/com/juick/xmpp/s2s/JuickBot.java
@@ -19,8 +19,13 @@ import java.util.regex.Pattern;
* @author ugnich
*/
public class JuickBot {
+ XMPPComponent xmpp;
+ public JuickBot(XMPPComponent xmpp, JID JuickJID) {
+ this.xmpp = xmpp;
+ this.JuickJID = JuickJID;
+ }
- public static final JID JuickJID = new JID("juick", "juick.com", "Juick");
+ public final JID JuickJID;
private static final String HELPTEXT =
"@username text - Send private message\n"
+ "*tagname Blah-blah-blah - Post a message with tag 'tagname'\n"
@@ -55,7 +60,7 @@ public class JuickBot {
+ "\n"
+ "Read more: http://juick.com/help/";
- public static boolean incomingPresence(Presence p) throws Exception {
+ public boolean incomingPresence(Presence p) throws Exception {
final String username = p.to.Username.toLowerCase();
final boolean toJuick = username.equals("juick");
@@ -64,14 +69,12 @@ public class JuickBot {
reply.from = new JID(p.to.Username, p.to.Host, null);
reply.to = new JID(p.from.Username, p.from.Host, null);
reply.type = Presence.Type.unsubscribe;
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
return true;
} else if (p.type.equals(Presence.Type.probe)) {
int uid_to = 0;
if (!toJuick) {
- synchronized (XMPPComponent.sqlSync) {
- uid_to = UserQueries.getUIDbyName(XMPPComponent.sql, username);
- }
+ uid_to = UserQueries.getUIDbyName(xmpp.sql, username);
}
if (toJuick || uid_to > 0) {
@@ -80,12 +83,12 @@ public class JuickBot {
reply.from.Resource = "Juick";
reply.to = p.from;
reply.priority = 10;
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
} else {
Presence reply = new Presence(p.to, p.from, Presence.Type.error);
reply.id = p.id;
reply.addChild(new Error(Error.Type.cancel, "item-not-found"));
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
return true;
}
return true;
@@ -94,50 +97,46 @@ public class JuickBot {
if (toJuick) {
canSubscribe = true;
} else {
- synchronized (XMPPComponent.sqlSync) {
- int uid_to = UserQueries.getUIDbyName(XMPPComponent.sql, username);
- if (uid_to > 0) {
- PMQueries.addPMinRoster(XMPPComponent.sql, uid_to, p.from.Bare());
- canSubscribe = true;
- }
+ int uid_to = UserQueries.getUIDbyName(xmpp.sql, username);
+ if (uid_to > 0) {
+ PMQueries.addPMinRoster(xmpp.sql, uid_to, p.from.Bare());
+ canSubscribe = true;
}
}
if (canSubscribe) {
Presence reply = new Presence(p.to, p.from, Presence.Type.subscribed);
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
reply.from.Resource = "Juick";
reply.priority = 10;
reply.type = null;
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
return true;
} else {
Presence reply = new Presence(p.to, p.from, Presence.Type.error);
reply.id = p.id;
reply.addChild(new Error(Error.Type.cancel, "item-not-found"));
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
return true;
}
} else if (p.type.equals(Presence.Type.unsubscribe)) {
if (!toJuick) {
- synchronized (XMPPComponent.sqlSync) {
- int uid_to = UserQueries.getUIDbyName(XMPPComponent.sql, username);
- if (uid_to > 0) {
- PMQueries.removePMinRoster(XMPPComponent.sql, uid_to, p.from.Bare());
- }
+ int uid_to = UserQueries.getUIDbyName(xmpp.sql, username);
+ if (uid_to > 0) {
+ PMQueries.removePMinRoster(xmpp.sql, uid_to, p.from.Bare());
}
}
Presence reply = new Presence(p.to, p.from, Presence.Type.unsubscribed);
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
}
return false;
}
- public static boolean incomingMessage(Message msg) throws Exception {
+ public boolean incomingMessage(Message msg) throws Exception {
if (msg.body == null || msg.body.isEmpty()) {
return true;
}
@@ -146,11 +145,9 @@ public class JuickBot {
User user_from = null;
String signuphash = "";
- synchronized (XMPPComponent.sqlSync) {
- user_from = UserQueries.getUserByJID(XMPPComponent.sql, msg.from.Bare());
- if (user_from == null) {
- signuphash = UserQueries.getSignUpHashByJID(XMPPComponent.sql, msg.from.Bare());
- }
+ user_from = UserQueries.getUserByJID(xmpp.sql, msg.from.Bare());
+ if (user_from == null) {
+ signuphash = UserQueries.getSignUpHashByJID(xmpp.sql, msg.from.Bare());
}
if (user_from == null) {
@@ -160,7 +157,7 @@ public class JuickBot {
} else {
reply.body = "Внимание, системное сообщение!\nВаш JabberID не обнаружен в списке доверенных. Для того, чтобы отправить сообщение пользователю " + username + "@juick.com, пожалуйста зарегистрируйте свой JabberID в системе: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nЕсли у вас уже есть учетная запись на Juick, вы сможете присоединить этот JabberID к ней.\n\nWarning, system message!\nYour JabberID is not found in our server's white list. To send a message to " + username + "@juick.com, please sign up: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nIf you already have an account on Juick, you will be proposed to attach this JabberID to your existing account.";
}
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
return true;
}
@@ -168,24 +165,19 @@ public class JuickBot {
return incomingMessageJuick(user_from, msg);
}
- int uid_to = 0;
- synchronized (XMPPComponent.sqlSync) {
- uid_to = UserQueries.getUIDbyName(XMPPComponent.sql, username);
- }
+ int uid_to = UserQueries.getUIDbyName(xmpp.sql, username);
if (uid_to == 0) {
Message reply = new Message(msg.to, msg.from, Message.Type.error);
reply.id = msg.id;
reply.addChild(new Error(Error.Type.cancel, "item-not-found"));
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
return true;
}
boolean success = false;
- synchronized (XMPPComponent.sqlSync) {
- if (!UserQueries.isInBLAny(XMPPComponent.sql, uid_to, user_from.getUID())) {
- success = PMQueries.createPM(XMPPComponent.sql, user_from.getUID(), uid_to, msg.body);
- }
+ if (!UserQueries.isInBLAny(xmpp.sql, uid_to, user_from.getUID())) {
+ success = PMQueries.createPM(xmpp.sql, user_from.getUID(), uid_to, msg.body);
}
if (success) {
@@ -193,29 +185,22 @@ public class JuickBot {
m.from = new JID("juick", "juick.com", null);
m.to = new JID(Integer.toString(uid_to), "push.juick.com", null);
JuickMessage jmsg = new JuickMessage();
- synchronized (XMPPComponent.sqlSync) {
- jmsg.setUser(UserQueries.getUserByUID(XMPPComponent.sql, user_from.getUID()));
- }
+ jmsg.setUser(user_from);
jmsg.setText(msg.body);
m.childs.add(jmsg);
- XMPPComponent.connRouter.router.send(m.toString());
+ xmpp.router.send(m.toString());
m.to.Host = "ws.juick.com";
- XMPPComponent.connRouter.router.send(m.toString());
+ xmpp.router.send(m.toString());
- String jid;
+ List<String> jids;
boolean inroster = false;
- synchronized (XMPPComponent.sqlSync) {
- jid = UserQueries.getJIDbyUID(XMPPComponent.sql, uid_to);
- if (jid != null) {
- inroster = PMQueries.havePMinRoster(XMPPComponent.sql, user_from.getUID(), jid);
- }
- }
-
- if (jid != null) {
+ jids = UserQueries.getJIDsbyUID(xmpp.sql, uid_to);
+ for (String jid : jids) {
Message mm = new Message();
mm.to = new JID(jid);
mm.type = Message.Type.chat;
+ inroster = PMQueries.havePMinRoster(xmpp.sql, user_from.getUID(), jid);
if (inroster) {
mm.from = new JID(jmsg.getUser().getUName(), "juick.com", "Juick");
mm.body = msg.body;
@@ -223,21 +208,20 @@ public class JuickBot {
mm.from = new JID("juick", "juick.com", "Juick");
mm.body = "Private message from @" + jmsg.getUser().getUName() + ":\n" + msg.body;
}
- XMPPComponent.sendOut(mm);
+ xmpp.sendOut(mm);
}
-
} else {
Message reply = new Message(msg.to, msg.from, Message.Type.error);
reply.id = msg.id;
reply.addChild(new Error(Error.Type.cancel, "not-allowed"));
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
}
return true;
}
private static Pattern regexPM = Pattern.compile("^\\@(\\S+)\\s+([\\s\\S]+)$");
- public static boolean incomingMessageJuick(User user_from, Message msg) throws Exception {
+ public boolean incomingMessageJuick(User user_from, Message msg) throws Exception {
String command = msg.body.trim();
int commandlen = command.length();
@@ -274,59 +258,54 @@ public class JuickBot {
return false;
}
- private static void commandPing(Message m) throws Exception {
+ private void commandPing(Message m) throws Exception {
Presence p = new Presence(JuickJID, m.from);
p.priority = 10;
- XMPPComponent.sendOut(p);
+ xmpp.sendOut(p);
Message reply = new Message(JuickJID, m.from, Message.Type.chat);
reply.body = "PONG";
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
}
- private static void commandHelp(Message m) throws Exception {
+ private void commandHelp(Message m) throws Exception {
Message reply = new Message(JuickJID, m.from, Message.Type.chat);
reply.body = HELPTEXT;
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
}
- private static void commandLogin(Message m, User user_from) throws Exception {
+ private void commandLogin(Message m, User user_from) throws Exception {
Message reply = new Message(JuickJID, m.from, Message.Type.chat);
- reply.body = "http://juick.com/login?" + UserQueries.getHashByUID(XMPPComponent.sql, user_from.getUID());
- XMPPComponent.sendOut(reply);
+ reply.body = "http://juick.com/login?" + UserQueries.getHashByUID(xmpp.sql, user_from.getUID());
+ xmpp.sendOut(reply);
}
- private static void commandPM(Message m, User user_from, String user_to, String body) throws Exception {
+ private void commandPM(Message m, User user_from, String user_to, String body) throws Exception {
int ret = 0;
int uid_to = 0;
- String jid_to = null;
+ List<String> jids_to = null;
boolean haveInRoster = false;
- synchronized (XMPPComponent.sqlSync) {
- if (user_to.indexOf('@') > 0) {
- uid_to = UserQueries.getUIDbyJID(XMPPComponent.sql, user_to);
- } else {
- uid_to = UserQueries.getUIDbyName(XMPPComponent.sql, user_to);
- }
+ if (user_to.indexOf('@') > 0) {
+ uid_to = UserQueries.getUIDbyJID(xmpp.sql, user_to);
+ } else {
+ uid_to = UserQueries.getUIDbyName(xmpp.sql, user_to);
+ }
- if (uid_to > 0) {
- if (!UserQueries.isInBLAny(XMPPComponent.sql, uid_to, user_from.getUID())) {
- if (PMQueries.createPM(XMPPComponent.sql, user_from.getUID(), uid_to, body)) {
- jid_to = UserQueries.getJIDbyUID(XMPPComponent.sql, uid_to);
- if (jid_to != null) {
- haveInRoster = PMQueries.havePMinRoster(XMPPComponent.sql, user_from.getUID(), jid_to);
- }
- ret = 200;
- } else {
- ret = 500;
- }
+ if (uid_to > 0) {
+ if (!UserQueries.isInBLAny(xmpp.sql, uid_to, user_from.getUID())) {
+ if (PMQueries.createPM(xmpp.sql, user_from.getUID(), uid_to, body)) {
+ jids_to = UserQueries.getJIDsbyUID(xmpp.sql, uid_to);
+ ret = 200;
} else {
- ret = 403;
+ ret = 500;
}
} else {
- ret = 404;
+ ret = 403;
}
+ } else {
+ ret = 404;
}
if (ret == 200) {
@@ -337,15 +316,16 @@ public class JuickBot {
jmsg.setUser(user_from);
jmsg.setText(body);
msg.childs.add(jmsg);
- XMPPComponent.connRouter.router.send(msg.toString());
+ xmpp.router.send(msg.toString());
msg.to.Host = "ws.juick.com";
- XMPPComponent.connRouter.router.send(msg.toString());
+ xmpp.router.send(msg.toString());
- if (jid_to != null) {
+ for (String jid : jids_to) {
Message mm = new Message();
- mm.to = new JID(jid_to);
+ mm.to = new JID(jid);
mm.type = Message.Type.chat;
+ haveInRoster = PMQueries.havePMinRoster(xmpp.sql, user_from.getUID(), jid);
if (haveInRoster) {
mm.from = new JID(user_from.getUName(), "juick.com", "Juick");
mm.body = body;
@@ -353,7 +333,7 @@ public class JuickBot {
mm.from = new JID("juick", "juick.com", "Juick");
mm.body = "Private message from @" + user_from.getUName() + ":\n" + body;
}
- XMPPComponent.sendOut(mm);
+ xmpp.sendOut(mm);
}
}
@@ -365,22 +345,17 @@ public class JuickBot {
reply.type = Message.Type.error;
reply.body = "Error " + ret;
}
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
}
- private static void commandBLShow(Message m, User user_from) throws Exception {
- List<User> blusers;
- List<String> bltags;
-
- synchronized (XMPPComponent.sqlSync) {
- blusers = UserQueries.getUserBLUsers(XMPPComponent.sql, user_from.getUID());
- bltags = TagQueries.getUserBLTags(XMPPComponent.sql, user_from.getUID());
- }
+ private void commandBLShow(Message m, User user_from) throws Exception {
+ List<User> blusers = UserQueries.getUserBLUsers(xmpp.sql, user_from.getUID());
+ List<String> bltags = TagQueries.getUserBLTags(xmpp.sql, user_from.getUID());
String txt = "";
if (bltags.size() > 0) {
- for (int i = 0; i < bltags.size(); i++) {
- txt += "*" + bltags.get(i) + "\n";
+ for (String bltag : bltags) {
+ txt += "*" + bltag + "\n";
}
if (blusers.size() > 0) {
@@ -388,8 +363,8 @@ public class JuickBot {
}
}
if (blusers.size() > 0) {
- for (int i = 0; i < blusers.size(); i++) {
- txt += "@" + blusers.get(i).getUName() + "\n";
+ for (User bluser : blusers) {
+ txt += "@" + bluser.getUName() + "\n";
}
}
if (txt.isEmpty()) {
@@ -398,6 +373,6 @@ public class JuickBot {
Message reply = new Message(JuickJID, m.from, Message.Type.chat);
reply.body = txt;
- XMPPComponent.sendOut(reply);
+ xmpp.sendOut(reply);
}
}
diff --git a/src/main/java/com/juick/xmpp/s2s/XMPPComponent.java b/src/main/java/com/juick/xmpp/s2s/XMPPComponent.java
index 13df5fd0..d0b231e2 100644
--- a/src/main/java/com/juick/xmpp/s2s/XMPPComponent.java
+++ b/src/main/java/com/juick/xmpp/s2s/XMPPComponent.java
@@ -1,21 +1,27 @@
package com.juick.xmpp.s2s;
-import com.juick.xmpp.Stanza;
-import com.juick.xmpp.StanzaChild;
+import com.juick.User;
+import com.juick.server.MessagesQueries;
+import com.juick.server.SubscriptionsQueries;
+import com.juick.server.UserQueries;
+import com.juick.xmpp.*;
import com.juick.xmpp.extensions.JuickMessage;
+import com.juick.xmpp.extensions.Nickname;
+import com.juick.xmpp.extensions.XOOB;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.xmlpull.v1.XmlPullParserException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -26,50 +32,51 @@ import java.util.logging.Logger;
*
* @author ugnich
*/
-public class XMPPComponent implements ServletContextListener {
-
- private static final Logger LOGGER = Logger.getLogger(XMPPComponent.class.getName());
-
- public static final ExecutorService executorService = Executors.newCachedThreadPool();
-
- public static String HOSTNAME = null;
- public static String STATSFILE = null;
- public static String keystore;
- public static String keystorePassword;
- public static List<String> brokenSSLhosts;
- public static ConnectionRouter connRouter;
- static final List<ConnectionIn> inConnections = Collections.synchronizedList(new ArrayList<>());
- static final List<ConnectionOut> outConnections = Collections.synchronizedList(new ArrayList<>());
- static final List<CacheEntry> outCache = Collections.synchronizedList(new ArrayList<>());
- static final Integer sqlSync = 0;
- static java.sql.Connection sql;
- final public static HashMap<String, StanzaChild> childParsers = new HashMap<>();
-
- public static void addConnectionIn(ConnectionIn c) {
+public class XMPPComponent implements ServletContextListener, Stream.StreamListener,
+ Message.MessageListener, Iq.IqListener, Presence.PresenceListener {
+
+ private static final Logger logger = Logger.getLogger(XMPPComponent.class.getName());
+
+ public final ExecutorService executorService = Executors.newCachedThreadPool();
+ StreamComponent router;
+ JuickBot bot;
+
+ public String HOSTNAME, componentName;
+ public String STATSFILE = null;
+ public String keystore;
+ public String keystorePassword;
+ public List<String> brokenSSLhosts;
+ final List<ConnectionIn> inConnections = Collections.synchronizedList(new ArrayList<>());
+ final List<ConnectionOut> outConnections = Collections.synchronizedList(new ArrayList<>());
+ final List<CacheEntry> outCache = Collections.synchronizedList(new ArrayList<>());
+ JdbcTemplate sql;
+ final public HashMap<String, StanzaChild> childParsers = new HashMap<>();
+
+ public void addConnectionIn(ConnectionIn c) {
synchronized (inConnections) {
inConnections.add(c);
}
}
- public static void addConnectionOut(ConnectionOut c) {
+ public void addConnectionOut(ConnectionOut c) {
synchronized (outConnections) {
outConnections.add(c);
}
}
- public static void removeConnectionIn(ConnectionIn c) {
+ public void removeConnectionIn(ConnectionIn c) {
synchronized (inConnections) {
inConnections.remove(c);
}
}
- public static void removeConnectionOut(ConnectionOut c) {
+ public void removeConnectionOut(ConnectionOut c) {
synchronized (outConnections) {
outConnections.remove(c);
}
}
- public static String getFromCache(String hostname) {
+ public String getFromCache(String hostname) {
CacheEntry ret = null;
synchronized (outCache) {
for (Iterator<CacheEntry> i = outCache.iterator(); i.hasNext();) {
@@ -84,7 +91,7 @@ public class XMPPComponent implements ServletContextListener {
return (ret != null) ? ret.xml : null;
}
- public static ConnectionOut getConnectionOut(String hostname, boolean needReady) {
+ public ConnectionOut getConnectionOut(String hostname, boolean needReady) {
synchronized (outConnections) {
for (ConnectionOut c : outConnections) {
if (c.to != null && c.to.equals(hostname) && (!needReady || c.streamReady)) {
@@ -95,7 +102,7 @@ public class XMPPComponent implements ServletContextListener {
return null;
}
- public static ConnectionIn getConnectionIn(String streamID) {
+ public ConnectionIn getConnectionIn(String streamID) {
synchronized (inConnections) {
for (ConnectionIn c : inConnections) {
if (c.streamID != null && c.streamID.equals(streamID)) {
@@ -106,11 +113,11 @@ public class XMPPComponent implements ServletContextListener {
return null;
}
- public static void sendOut(Stanza s) {
+ public void sendOut(Stanza s) {
sendOut(s.to.Host, s.toString());
}
- public static void sendOut(String hostname, String xml) {
+ public void sendOut(String hostname, String xml) {
boolean haveAnyConn = false;
ConnectionOut connOut = null;
@@ -131,7 +138,7 @@ public class XMPPComponent implements ServletContextListener {
try {
connOut.sendStanza(xml);
} catch (IOException e) {
- LOGGER.warning("STREAM TO " + connOut.to + " " + connOut.streamID + " ERROR: " + e.toString());
+ logger.warning("STREAM TO " + connOut.to + " " + connOut.streamID + " ERROR: " + e.toString());
}
return;
}
@@ -152,12 +159,11 @@ public class XMPPComponent implements ServletContextListener {
}
if (!haveAnyConn) {
- ConnectionOut connectionOut = null;
try {
- connectionOut = new ConnectionOut(hostname);
- XMPPComponent.executorService.submit(connectionOut);
+ ConnectionOut connectionOut = new ConnectionOut(this, hostname);
+ executorService.submit(connectionOut);
} catch (CertificateException | UnrecoverableKeyException | NoSuchAlgorithmException | XmlPullParserException | KeyStoreException | KeyManagementException | IOException e) {
- LOGGER.log(Level.SEVERE, "s2s out error", e);
+ logger.log(Level.SEVERE, "s2s out error", e);
}
}
}
@@ -165,45 +171,74 @@ public class XMPPComponent implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
- LOGGER.info("component initialized");
- executorService.submit(() -> {
- Properties conf = new Properties();
- try {
- conf.load(sce.getServletContext().getResourceAsStream("/WEB-INF/juick.conf"));
- HOSTNAME = conf.getProperty("hostname");
- String componentName = conf.getProperty("componentname");
- STATSFILE = conf.getProperty("statsfile");
- keystore = conf.getProperty("keystore");
- keystorePassword = conf.getProperty("keystore_password");
- brokenSSLhosts = Arrays.asList(conf.getProperty("broken_ssl_hosts", "").split(","));
- Class.forName("com.mysql.jdbc.Driver");
- sql = DriverManager.getConnection("jdbc:mysql://localhost/juick?autoReconnect=true&user=" +
- conf.getProperty("mysql_username", "") + "&password=" + conf.getProperty("mysql_password", ""));
-
- childParsers.put(JuickMessage.XMLNS, new JuickMessage());
- executorService.submit(() -> connRouter = new ConnectionRouter(componentName, conf.getProperty("xmpp_password")));
- executorService.submit(new ConnectionListener());
- executorService.submit(new CleaningUp());
- } catch (Exception e) {
- LOGGER.log(Level.SEVERE, "XMPPComponent error", e);
- }
- });
+ logger.info("component initialized");
+ Properties conf = new Properties();
+ try {
+ conf.load(sce.getServletContext().getResourceAsStream("/WEB-INF/juick.conf"));
+ HOSTNAME = conf.getProperty("hostname");
+ componentName = conf.getProperty("componentname");
+ JID Jid = new JID(conf.getProperty("xmppbot_jid"));
+ STATSFILE = conf.getProperty("statsfile");
+ keystore = conf.getProperty("keystore");
+ keystorePassword = conf.getProperty("keystore_password");
+ brokenSSLhosts = Arrays.asList(conf.getProperty("broken_ssl_hosts", "").split(","));
+ DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver"));
+ dataSource.setUrl(conf.getProperty("datasource_url"));
+ sql = new JdbcTemplate(dataSource);
+ bot = new JuickBot(this, Jid);
+
+ childParsers.put(JuickMessage.XMLNS, new JuickMessage());
+
+ executorService.submit(() -> {
+ Socket routerSocket = null;
+ try {
+ routerSocket = new Socket("localhost", 5347);
+ router = new StreamComponent(new JID("s2s"), routerSocket.getInputStream(), routerSocket.getOutputStream(), conf.getProperty("xmpp_password"));
+ router.addChildParser(new JuickMessage());
+ router.addListener((Stream.StreamListener) this);
+ router.addListener((Message.MessageListener) this);
+ router.addListener((Iq.IqListener) this);
+ router.startParsing();
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "router error", e);
+ }
+ });
+ executorService.submit(() -> {
+ final ServerSocket listener = new ServerSocket(5269);
+ logger.info("s2s listener ready");
+ while (true) {
+ try {
+ Socket socket = listener.accept();
+ ConnectionIn client = new ConnectionIn(this, bot, socket);
+ addConnectionIn(client);
+ executorService.submit(client);
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, "s2s error", e);
+ }
+ }
+ });
+ executorService.submit(new CleaningUp(this));
+
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, "XMPPComponent error", e);
+ }
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
- synchronized (XMPPComponent.outConnections) {
- for (Iterator<ConnectionOut> i = XMPPComponent.outConnections.iterator(); i.hasNext();) {
+ synchronized (outConnections) {
+ for (Iterator<ConnectionOut> i = outConnections.iterator(); i.hasNext();) {
ConnectionOut c = i.next();
c.closeConnection();
i.remove();
}
}
- synchronized (XMPPComponent.inConnections) {
- for (Iterator<ConnectionIn> i = XMPPComponent.inConnections.iterator(); i.hasNext();) {
+ synchronized (inConnections) {
+ for (Iterator<ConnectionIn> i = inConnections.iterator(); i.hasNext();) {
ConnectionIn c = i.next();
c.closeConnection();
i.remove();
@@ -211,42 +246,198 @@ public class XMPPComponent implements ServletContextListener {
}
try {
- XMPPComponent.connRouter.closeConnection();
+ closeRouterConnection();
} catch (IOException e) {
- LOGGER.log(Level.WARNING, "router warning", e);
+ logger.log(Level.WARNING, "router warning", e);
}
+ executorService.shutdown();
+ logger.info("component destroyed");
+ }
+ public void closeRouterConnection() throws IOException {
+ router.logoff();
+ }
- synchronized (XMPPComponent.sqlSync) {
- if (XMPPComponent.sql != null) {
- try {
- XMPPComponent.sql.close();
- XMPPComponent.sql = null;
- } catch (SQLException e) {
- LOGGER.warning("SQL ERROR: " + e);
+ public void sendJuickMessage(JuickMessage jmsg) {
+ List<String> jids = new ArrayList<>();
+
+ if (jmsg.FriendsOnly) {
+ jids = SubscriptionsQueries.getJIDSubscribedToUser(sql, jmsg.getUser().getUID(), jmsg.FriendsOnly);
+ } else {
+ List<User> users = SubscriptionsQueries.getSubscribedUsers(sql, jmsg.getUser().getUID(), jmsg.getMID());
+ for (User user : users) {
+ for (String jid : UserQueries.getJIDsbyUID(sql, user.getUID())) {
+ jids.add(jid);
}
}
}
- // Now deregister JDBC drivers in this context's ClassLoader:
- // Get the webapp's ClassLoader
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- // Loop through all drivers
- Enumeration<Driver> 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 {
- LOGGER.info(String.format("Deregistering JDBC driver %s", driver.toString()));
- DriverManager.deregisterDriver(driver);
- } catch (SQLException ex) {
- LOGGER.log(Level.SEVERE, String.format("Error deregistering JDBC driver %s", driver), ex);
- }
+
+ String txt = "@" + jmsg.getUser().getUName() + ":" + jmsg.getTagsString() + "\n";
+ String attachment = jmsg.getAttachmentURL();
+ if (attachment != null) {
+ txt += attachment + "\n";
+ }
+ txt += jmsg.getText() + "\n\n";
+ txt += "#" + jmsg.getMID() + " http://juick.com/" + jmsg.getMID();
+
+ Nickname nick = new Nickname();
+ nick.Nickname = "@" + jmsg.getUser().getUName();
+
+ com.juick.xmpp.Message msg = new com.juick.xmpp.Message();
+ msg.from = bot.JuickJID;
+ msg.body = txt;
+ msg.type = Message.Type.chat;
+ msg.thread = "juick-" + jmsg.getMID();
+ msg.addChild(jmsg);
+ msg.addChild(nick);
+ if (attachment != null) {
+ XOOB oob = new XOOB();
+ oob.URL = attachment;
+ msg.addChild(oob);
+ }
+
+ for (String jid : jids) {
+ msg.to = new JID(jid);
+ sendOut(msg);
+ }
+ }
+
+ public void sendJuickComment(JuickMessage jmsg) {
+ List<User> users;
+ String replyQuote;
+ String replyTo;
+
+ users = SubscriptionsQueries.getUsersSubscribedToComments(sql, jmsg.getMID(), jmsg.getUser().getUID());
+ com.juick.Message replyMessage = jmsg.ReplyTo > 0 ? MessagesQueries.getReply(sql, jmsg.getMID(), jmsg.ReplyTo)
+ : MessagesQueries.getMessage(sql, jmsg.getMID());
+ replyTo = replyMessage.getUser().getUName();
+ replyQuote = getReplyQuote(replyMessage);
+
+ String txt = "Reply by @" + jmsg.getUser().getUName() + ":\n" + replyQuote + "\n@" + replyTo + " ";
+ String attachment = jmsg.getAttachmentURL();
+ if (attachment != null) {
+ txt += attachment + "\n";
+ }
+ txt += jmsg.getText() + "\n\n" + "#" + jmsg.getMID() + "/" + jmsg.getRID() + " http://juick.com/" + jmsg.getMID() + "#" + jmsg.getRID();
+
+ com.juick.xmpp.Message msg = new com.juick.xmpp.Message();
+ msg.from = bot.JuickJID;
+ msg.body = txt;
+ msg.type = Message.Type.chat;
+ msg.addChild(jmsg);
+ for (User user : users) {
+ for (String jid : UserQueries.getJIDsbyUID(sql, user.getUID())) {
+ msg.to = new JID(jid);
+ sendOut(msg);
+ }
+ }
+ }
+
+ private String getReplyQuote(com.juick.Message q) {
+ String quote = q.getText();
+ if (quote.length() > 50) {
+ quote = ">" + quote.substring(0, 47).replace('\n', ' ') + "...\n";
+ } else if (quote.length() > 0) {
+ quote = ">" + quote.replace('\n', ' ') + "\n";
+ }
+ return quote;
+ }
+
+ public void sendJuickRecommendation(JuickMessage recomm) {
+ List<User> users;
+ JuickMessage jmsg;
+ jmsg = new JuickMessage(MessagesQueries.getMessage(sql, recomm.getMID()));
+ users = SubscriptionsQueries.getUsersSubscribedToUserRecommendations(sql,
+ recomm.getUser().getUID(), recomm.getMID(), jmsg.getUser().getUID());
+
+ String txt = "Recommended by @" + recomm.getUser().getUName() + ":\n";
+ txt += "@" + jmsg.getUser().getUName() + ":" + jmsg.getTagsString() + "\n";
+ String attachment = jmsg.getAttachmentURL();
+ if (attachment != null) {
+ txt += attachment + "\n";
+ }
+ txt += jmsg.getText() + "\n\n";
+ txt += "#" + jmsg.getMID();
+ if (jmsg.Replies > 0) {
+ if (jmsg.Replies % 10 == 1 && jmsg.Replies % 100 != 11) {
+ txt += " (" + jmsg.Replies + " reply)";
} else {
- // driver was not registered by the webapp's ClassLoader and may be in use elsewhere
- LOGGER.log(Level.SEVERE, String.format("Not deregistering JDBC driver %s as it does not belong to this webapp's ClassLoader", driver));
+ txt += " (" + jmsg.Replies + " replies)";
}
}
- executorService.shutdown();
- LOGGER.info("component destroyed");
+ txt += " http://juick.com/" + jmsg.getMID();
+
+ Nickname nick = new Nickname();
+ nick.Nickname = "@" + jmsg.getUser().getUName();
+
+ com.juick.xmpp.Message msg = new com.juick.xmpp.Message();
+ msg.from = bot.JuickJID;
+ msg.body = txt;
+ msg.type = Message.Type.chat;
+ msg.thread = "juick-" + jmsg.getMID();
+ msg.addChild(jmsg);
+ msg.addChild(nick);
+ if (attachment != null) {
+ XOOB oob = new XOOB();
+ oob.URL = attachment;
+ msg.addChild(oob);
+ }
+
+ for (User user : users) {
+ for (String jid : UserQueries.getJIDsbyUID(sql, user.getUID())) {
+ msg.to = new JID(jid);
+ sendOut(msg);
+ }
+ }
+ }
+
+ @Override
+ public boolean onIq(Iq iq) {
+ JID jid = iq.to;
+ if (!jid.Host.equals(componentName)) {
+ logger.info("STREAM ROUTER (IQ): " + iq.toString());
+ sendOut(iq);
+ }
+ return false;
+ }
+
+ @Override
+ public void onMessage(Message xmsg) {
+ logger.info("STREAM ROUTER (PROCESS): " + xmsg.toString());
+ JuickMessage jmsg = (JuickMessage) xmsg.getChild(JuickMessage.XMLNS);
+ JID jid = xmsg.to;
+ if (jid.Host.equals(componentName)) {
+ if (jmsg != null) {
+ if (jid.Username != null && jid.Username.equals("recomm")) {
+ sendJuickRecommendation(jmsg);
+ } else {
+ if (jmsg.getRID() > 0) {
+ sendJuickComment(jmsg);
+ } else if (jmsg.getMID() > 0) {
+ sendJuickMessage(jmsg);
+ }
+ }
+ }
+ } else {
+ sendOut(xmsg);
+ }
+ }
+
+ @Override
+ public void onPresence(Presence presence) {
+ JID jid = presence.to;
+ if (!jid.Host.equals(componentName)) {
+ logger.info("STREAM ROUTER (PRESENCE): " + presence.toString());
+ sendOut(presence);
+ }
+ }
+
+ @Override
+ public void onStreamReady() {
+ logger.info("STREAM ROUTER (READY)");
+ }
+
+ @Override
+ public void onStreamFail(Exception ex) {
+ logger.log(Level.SEVERE, "STREAM ROUTER (FAIL)", ex);
}
}