Browse Source

sorted methods alphabetically

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
main
Stephan Richter 8 months ago
parent
commit
9e363cc0e8
  1. 93
      src/main/java/de/srsoftware/widerhall/Configuration.java
  2. 151
      src/main/java/de/srsoftware/widerhall/Util.java
  3. 48
      src/main/java/de/srsoftware/widerhall/data/Database.java
  4. 29
      src/main/java/de/srsoftware/widerhall/data/ListMember.java
  5. 122
      src/main/java/de/srsoftware/widerhall/mail/ImapClient.java
  6. 37
      src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java

93
src/main/java/de/srsoftware/widerhall/Configuration.java

@ -17,6 +17,45 @@ public class Configuration { @@ -17,6 +17,45 @@ public class Configuration {
private JSONObject data;
private File file;
public File archiveDir() {
var locations = locations();
if (!locations.containsKey(ARCHIVE)) locations.put(ARCHIVE, String.join(File.separator,baseDir(),"archive"));
return new File((String) locations.get(ARCHIVE));
}
public String baseDir() {
var locations = locations();
if (!locations.containsKey(BASE)) locations.put(BASE,System.getProperty("user.dir"));
return (String) locations.get(BASE);
}
public String baseUrl() {
if (!data.containsKey(BASE_URL)) data.put(BASE_URL,"http://localhost");
return (String) data.get(BASE_URL);
}
public File configFile() {
var locations = locations();
if (!locations.containsKey(CONFIG)) locations.put(CONFIG, String.join(File.separator,baseDir(),"config","config.json"));
return new File((String) locations.get(CONFIG));
}
public File dbFile() {
var locations = locations();
if (!locations.containsKey(DB)) locations.put(DB, String.join(File.separator,baseDir(),"db","db.sqlite3"));
return new File((String) locations.get(DB));
}
public Configuration dbFile(File dbFile){
var locations = locations();
locations.put(DB,dbFile.toString());
return this;
}
public File file() {
return file;
}
public static Configuration instance() {
if (singleton == null) singleton = new Configuration().setDefaults();
return singleton;
@ -42,6 +81,12 @@ public class Configuration { @@ -42,6 +81,12 @@ public class Configuration {
return this;
}
private JSONObject locations() {
Object o = data.get(LOCATIONS);
if (!(o instanceof JSONObject)) data.put(LOCATIONS,o = new JSONObject());
return (JSONObject) o;
}
public Configuration save(File file) throws IOException {
this.file = file;
return save();
@ -64,57 +109,9 @@ public class Configuration { @@ -64,57 +109,9 @@ public class Configuration {
return this;
}
private JSONObject locations() {
Object o = data.get(LOCATIONS);
if (!(o instanceof JSONObject)) data.put(LOCATIONS,o = new JSONObject());
return (JSONObject) o;
}
public String baseDir() {
var locations = locations();
if (!locations.containsKey(BASE)) locations.put(BASE,System.getProperty("user.dir"));
return (String) locations.get(BASE);
}
public File configFile() {
var locations = locations();
if (!locations.containsKey(CONFIG)) locations.put(CONFIG, String.join(File.separator,baseDir(),"config","config.json"));
return new File((String) locations.get(CONFIG));
}
public File dbFile() {
var locations = locations();
if (!locations.containsKey(DB)) locations.put(DB, String.join(File.separator,baseDir(),"db","db.sqlite3"));
return new File((String) locations.get(DB));
}
public Configuration dbFile(File dbFile){
var locations = locations();
locations.put(DB,dbFile.toString());
return this;
}
public File archiveDir() {
var locations = locations();
if (!locations.containsKey(ARCHIVE)) locations.put(ARCHIVE, String.join(File.separator,baseDir(),"archive"));
return new File((String) locations.get(ARCHIVE));
}
public int serverPort() {
if (!data.containsKey(PORT)) data.put(PORT,80L);
var o = data.get(PORT);
return (int) (long) o;
}
public String baseUrl() {
if (!data.containsKey(BASE_URL)) data.put(BASE_URL,"http://localhost");
return (String) data.get(BASE_URL);
}
public File file() {
return file;
}
}

151
src/main/java/de/srsoftware/widerhall/Util.java

@ -28,19 +28,33 @@ public class Util { @@ -28,19 +28,33 @@ public class Util {
private static final MessageDigest SHA256 = getSha256();
private static final String EMAIL_PATTERN = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$";
public static String urlEncode(Map<String, Object> data) {
String params = data.entrySet()
.stream()
.map(entry -> encode(entry.getKey()) + "=" + encode(entry.getValue()))
.collect(Collectors.joining("&"));
return params;
public static String dropEmail(String tx) {
return tx.replaceAll( "[.\\-\\w]+@[.\\-\\w]+", "[email_removed]");
}
private static String encode(Object value) {
return URLEncoder.encode(value.toString(), StandardCharsets.UTF_8);
}
public static boolean getCheckbox(HttpServletRequest req, String key) {
return "on".equals(req.getParameter(key));
}
public static MailingList getMailingList(HttpServletRequest req) {
var listEmail = req.getParameter(LIST);
if (listEmail == null || listEmail.isBlank()) return null;
return MailingList.load(listEmail);
}
public static <T> T getNullable(ResultSet rs, String colName) throws SQLException {
final T val = (T) rs.getObject(colName);
return rs.wasNull() ? null : val;
}
public static String getPath(HttpServletRequest req) {
var path = req.getPathInfo();
return path == null ? INDEX : path.substring(1);
}
public static MessageDigest getSha256() {
try {
return MessageDigest.getInstance("SHA-256");
@ -50,9 +64,43 @@ public class Util { @@ -50,9 +64,43 @@ public class Util {
}
}
public static String sha256(String s) {
byte[] bytes = SHA256.digest(s.getBytes(StandardCharsets.UTF_8));
return hex(bytes);
/**
* Return the primary text content of the message.
*/
public static String getText(Part p) throws MessagingException, IOException {
// https://javaee.github.io/javamail/FAQ
if (p.isMimeType("text/*")) return (String)p.getContent();
if (p.isMimeType("multipart/alternative")) {
// prefer html text over plain text
Multipart mp = (Multipart)p.getContent();
String text = null;
for (int i = 0; i < mp.getCount(); i++) {
Part bp = mp.getBodyPart(i);
if (bp.isMimeType("text/plain")) {
if (text == null) text = getText(bp);
continue;
} else if (bp.isMimeType("text/html")) {
String s = getText(bp);
if (s != null) return s;
} else {
return getText(bp);
}
}
return text;
} else if (p.isMimeType("multipart/*")) {
Multipart mp = (Multipart)p.getContent();
for (int i = 0; i < mp.getCount(); i++) {
String s = getText(mp.getBodyPart(i));
if (s != null) return s;
}
}
return null;
}
public static User getUser(HttpServletRequest req) {
var o = req.getSession().getAttribute(USER);
return o instanceof User ? (User) o : null;
}
private static String hex(byte[] bytes) {
@ -67,14 +115,15 @@ public class Util { @@ -67,14 +115,15 @@ public class Util {
return (char)(upper < 10 ? '0'+upper : 'A'+upper-10)+""+(char)(lower < 10 ? '0'+lower : 'A'+lower-10);
}
public static String t(String tx, Object ... fills){
return Translation.get(Application.class,tx,fills);
}
public static boolean isEmail(String email) {
return email.matches(EMAIL_PATTERN);
}
public static String sha256(String s) {
byte[] bytes = SHA256.digest(s.getBytes(StandardCharsets.UTF_8));
return hex(bytes);
}
public static boolean simplePassword(String pass) {
if (pass.length() < 6) return true;
if (pass.length() < 8){
@ -98,75 +147,23 @@ public class Util { @@ -98,75 +147,23 @@ public class Util {
return false;
}
public static int unset(int value, int...flags) {
for (int flag : flags){
if ((value & flag) > 0) value ^= flag;
}
return value;
}
public static User getUser(HttpServletRequest req) {
var o = req.getSession().getAttribute(USER);
return o instanceof User ? (User) o : null;
}
public static String getPath(HttpServletRequest req) {
var path = req.getPathInfo();
return path == null ? INDEX : path.substring(1);
}
public static MailingList getMailingList(HttpServletRequest req) {
var listEmail = req.getParameter(LIST);
if (listEmail == null || listEmail.isBlank()) return null;
return MailingList.load(listEmail);
public static String t(String tx, Object ... fills){
return Translation.get(Application.class,tx,fills);
}
public static boolean getCheckbox(HttpServletRequest req, String key) {
return "on".equals(req.getParameter(key));
public static String urlEncode(Map<String, Object> data) {
String params = data.entrySet()
.stream()
.map(entry -> encode(entry.getKey()) + "=" + encode(entry.getValue()))
.collect(Collectors.joining("&"));
return params;
}
/**
* Return the primary text content of the message.
*/
public static String getText(Part p) throws MessagingException, IOException {
// https://javaee.github.io/javamail/FAQ
if (p.isMimeType("text/*")) return (String)p.getContent();
if (p.isMimeType("multipart/alternative")) {
// prefer html text over plain text
Multipart mp = (Multipart)p.getContent();
String text = null;
for (int i = 0; i < mp.getCount(); i++) {
Part bp = mp.getBodyPart(i);
if (bp.isMimeType("text/plain")) {
if (text == null) text = getText(bp);
continue;
} else if (bp.isMimeType("text/html")) {
String s = getText(bp);
if (s != null) return s;
} else {
return getText(bp);
}
}
return text;
} else if (p.isMimeType("multipart/*")) {
Multipart mp = (Multipart)p.getContent();
for (int i = 0; i < mp.getCount(); i++) {
String s = getText(mp.getBodyPart(i));
if (s != null) return s;
}
public static int unset(int value, int...flags) {
for (int flag : flags){
if ((value & flag) > 0) value ^= flag;
}
return null;
}
public static String dropEmail(String tx) {
return tx.replaceAll( "[.\\-\\w]+@[.\\-\\w]+", "[email_removed]");
}
public static <T> T getNullable(ResultSet rs, String colName) throws SQLException {
final T val = (T) rs.getObject(colName);
return rs.wasNull() ? null : val;
return value;
}
}

48
src/main/java/de/srsoftware/widerhall/data/Database.java

@ -137,30 +137,6 @@ public class Database { @@ -137,30 +137,6 @@ public class Database {
if (!sortFields.isEmpty()) sql.append(" ORDER BY ").append(String.join(", ",sortFields));
}
@Override
protected Request clone() {
Request clone = new Request(new StringBuilder(sql));
clone.where.putAll(where);
clone.values.putAll(values);
return clone;
}
/**
* finalize sql, save sql and arguments as compiled request
* @return
*/
public CompiledRequest compile(Object ...additionalArgs){
var args = new ArrayList<>();
applyValues(args);
applyConditions(args);
applyGrouping();
applySorting();
if (additionalArgs != null) {
for (Object arg : additionalArgs) args.add(arg);
}
return new CompiledRequest(sql.toString(),args);
}
/**
* apply values (for insert or update statements)
* @param args
@ -193,6 +169,30 @@ public class Database { @@ -193,6 +169,30 @@ public class Database {
}
}
@Override
protected Request clone() {
Request clone = new Request(new StringBuilder(sql));
clone.where.putAll(where);
clone.values.putAll(values);
return clone;
}
/**
* finalize sql, save sql and arguments as compiled request
* @return
*/
public CompiledRequest compile(Object ...additionalArgs){
var args = new ArrayList<>();
applyValues(args);
applyConditions(args);
applyGrouping();
applySorting();
if (additionalArgs != null) {
for (Object arg : additionalArgs) args.add(arg);
}
return new CompiledRequest(sql.toString(),args);
}
public Request groupBy(String column) {
groupBy = column;
return this;

29
src/main/java/de/srsoftware/widerhall/data/ListMember.java

@ -112,20 +112,6 @@ public class ListMember { @@ -112,20 +112,6 @@ public class ListMember {
return null;
}
public void sendConfirmationMail(ST template) throws SQLException, MessagingException {
var subject = t("[{}] Subscription complete!",list.name());
var data = new HashMap<String,Object>();
data.put(USER,user.safeMap());
data.put(LIST,list.minimalMap());
data.put(URL,Configuration.instance().baseUrl()+"/web/index");
if (list.isOpenForSubscribers()) data.put("open_list",true);
var text = template.add("data",data).render();
try {
list.smtp().send(list.email(),list.name(),user.email(),subject,text);
} catch (UnsupportedEncodingException e) {
LOG.warn("Failed to send list subscription confirmation!",e);
}
}
/**
* Create a new list member entry in the database.
* If the member has the state AWAITING_CONFIRMATION, a token is assigned with the member, too.
@ -374,6 +360,21 @@ public class ListMember { @@ -374,6 +360,21 @@ public class ListMember {
return this;
}
public void sendConfirmationMail(ST template) throws SQLException, MessagingException {
var subject = t("[{}] Subscription complete!",list.name());
var data = new HashMap<String,Object>();
data.put(USER,user.safeMap());
data.put(LIST,list.minimalMap());
data.put(URL,Configuration.instance().baseUrl()+"/web/index");
if (list.isOpenForSubscribers()) data.put("open_list",true);
var text = template.add("data",data).render();
try {
list.smtp().send(list.email(),list.name(),user.email(),subject,text);
} catch (UnsupportedEncodingException e) {
LOG.warn("Failed to send list subscription confirmation!",e);
}
}
public ListMember setState(int newState) throws SQLException {
Database.open()
.update(TABLE_NAME)

122
src/main/java/de/srsoftware/widerhall/mail/ImapClient.java

@ -33,28 +33,40 @@ public class ImapClient { @@ -33,28 +33,40 @@ public class ImapClient {
return this;
}
public ListeningThread doStop() {
stopped = true;
return this;
}
public ListeningThread dropListeners() {
listeners.clear();
return this;
}
@Override
public void run() {
while (!stopped) {
try {
sleep(5000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
try {
openInbox();
} catch (MessagingException e){
LOG.warn("Connection problem:",e);
problemListener.onImapException(e);
}
private void handle(Message message) throws MessagingException {
LOG.debug("Handling {}",message.getSubject());
for (MessageHandler listener : listeners) listener.onMessageReceived(message);
}
private void handleMessages() throws MessagingException {
LOG.debug("Reading email of {}:",username);
if (!inbox.isOpen()) inbox.open(IMAPFolder.READ_WRITE);
for (Message message : inbox.getMessages()){
if (message.isSet(Flags.Flag.SEEN)) continue;
handle(message);
Folder folder = message.getFolder();
if (!folder.isOpen()) folder.open(Folder.READ_WRITE);
message.setFlag(Flags.Flag.SEEN,true);
}
}
private Properties imapProps() {
Properties props = new Properties();
props.put(Constants.PROTOCOL,Constants.IMAPS);
return props;
}
private void openInbox() throws MessagingException {
LOG.debug("Connecting and logging in…");
Properties props = imapProps();
@ -73,40 +85,33 @@ public class ImapClient { @@ -73,40 +85,33 @@ public class ImapClient {
}
}
private void handleMessages() throws MessagingException {
LOG.debug("Reading email of {}:",username);
if (!inbox.isOpen()) inbox.open(IMAPFolder.READ_WRITE);
for (Message message : inbox.getMessages()){
if (message.isSet(Flags.Flag.SEEN)) continue;
handle(message);
Folder folder = message.getFolder();
if (!folder.isOpen()) folder.open(Folder.READ_WRITE);
message.setFlag(Flags.Flag.SEEN,true);
@Override
public void run() {
while (!stopped) {
try {
sleep(5000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
try {
openInbox();
} catch (MessagingException e){
LOG.warn("Connection problem:",e);
problemListener.onImapException(e);
}
}
}
private void handle(Message message) throws MessagingException {
LOG.debug("Handling {}",message.getSubject());
for (MessageHandler listener : listeners) listener.onMessageReceived(message);
}
private Properties imapProps() {
Properties props = new Properties();
props.put(Constants.PROTOCOL,Constants.IMAPS);
return props;
}
public ListeningThread doStop() {
stopped = true;
return this;
}
}
private class Heartbeat extends Thread{
private static final Logger LOG = LoggerFactory.getLogger(Heartbeat.class);
private boolean stopped = false;
public Heartbeat doStop() {
stopped = true;
return this;
}
@Override
public void run() {
while (!stopped){
@ -123,11 +128,6 @@ public class ImapClient { @@ -123,11 +128,6 @@ public class ImapClient {
}
}
}
public Heartbeat doStop() {
stopped = true;
return this;
}
}
public ImapClient(String host, int port, String username, String password, String folderName,ProblemListener listener) {
@ -165,25 +165,13 @@ public class ImapClient { @@ -165,25 +165,13 @@ public class ImapClient {
inbox.expunge();
}
public String host(){
return host;
}
public String username(){
return username;
}
public String password(){
return password;
public String folderName(){
return folderName;
}
public int port(){
return port;
}
public String folderName(){
return folderName;
public String host(){
return host;
}
public ImapClient move(Message message, String destinationFolder) throws MessagingException {
@ -200,6 +188,14 @@ public class ImapClient { @@ -200,6 +188,14 @@ public class ImapClient {
return this;
}
public String password(){
return password;
}
public int port(){
return port;
}
public ImapClient start() {
stop();
@ -225,4 +221,8 @@ public class ImapClient { @@ -225,4 +221,8 @@ public class ImapClient {
}
return this;
}
public String username(){
return username;
}
}

37
src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java

@ -81,6 +81,9 @@ public class SmtpClient { @@ -81,6 +81,9 @@ public class SmtpClient {
send(forward);
}
public String host() {
return host;
}
public SmtpClient login(){
if (session == null) {
@ -97,6 +100,20 @@ public class SmtpClient { @@ -97,6 +100,20 @@ public class SmtpClient {
return this;
}
public String password() {
return password;
}
public int port() {
return port;
}
public void send(Message message) throws MessagingException {
LOG.debug("Versende Mail…");
Transport.send(message,username,password);
LOG.debug("…versendet");
}
public void send(String senderAdress, String senderName, String receivers, String subject, String content) throws MessagingException, UnsupportedEncodingException {
login();
MimeMessage message = new MimeMessage(session);
@ -113,27 +130,7 @@ public class SmtpClient { @@ -113,27 +130,7 @@ public class SmtpClient {
send(message);
}
public void send(Message message) throws MessagingException {
LOG.debug("Versende Mail…");
Transport.send(message,username,password);
LOG.debug("…versendet");
}
public String host() {
return host;
}
public int port() {
return port;
}
public String username() {
return username;
}
public String password() {
return password;
}
}

Loading…
Cancel
Save