diff --git a/pom.xml b/pom.xml
index e4fd4ef..2739c40 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.example
Widerhall
- 0.0.5
+ 0.0.6
diff --git a/src/main/java/de/srsoftware/widerhall/data/ListMember.java b/src/main/java/de/srsoftware/widerhall/data/ListMember.java
index b0206fa..864d063 100644
--- a/src/main/java/de/srsoftware/widerhall/data/ListMember.java
+++ b/src/main/java/de/srsoftware/widerhall/data/ListMember.java
@@ -12,18 +12,30 @@ import java.util.*;
import static de.srsoftware.widerhall.Constants.*;
+/**
+ * @author Stephan Richter
+ * This class embodies the ListMembers table
+ */
public class ListMember {
- private static final Logger LOG = LoggerFactory.getLogger(ListMember.class);
public static final String TABLE_NAME = "ListMembers";
public static final int STATE_OWNER = 1;
public static final int STATE_SUBSCRIBER = 2;
public static final int STATE_AWAITING_CONFIRMATION = 4;
+ private static final Logger LOG = LoggerFactory.getLogger(ListMember.class);
private static final String LIST_EMAIL = "list_email";
private static final String USER_EMAIL = "user_email";
private static final String STATE = "state";
+
private final String listEmail,token,userEmail;
private final int state;
+ /**
+ * create a new list member object
+ * @param listEmail
+ * @param userEmail
+ * @param state
+ * @param token
+ */
public ListMember(String listEmail, String userEmail, int state, String token){
this.listEmail = listEmail;
this.userEmail = userEmail;
@@ -31,10 +43,21 @@ public class ListMember {
this.token = token;
}
+ /**
+ * tries to confirm the token:
+ * This method loads the list member, that is assigned with the token.
+ * If no db entry is found for the token, null is returned.
+ * If an entry is found, the respective User object is loaded.
+ * If no User object is assigned, null is returned.
+ * If a matching User object is present, the member's state is altered from AWAITING_CONFIRMATION to SUBSCRIBER and the token is dropped.
+ * @param token
+ * @return
+ * @throws SQLException
+ */
public static User confirm(String token) throws SQLException {
var rs = Database.open().select(TABLE_NAME).where(TOKEN,token).compile().exec();
if (rs.next()){
- var lm = new ListMember(rs.getString(LIST_EMAIL),rs.getString(USER_EMAIL),rs.getInt(STATE),rs.getString(TOKEN));
+ var lm = ListMember.from(rs);
rs.close();
User user = User.loadAll(List.of(lm.userEmail)).stream().findAny().orElse(null);
if (user != null){
@@ -54,6 +77,15 @@ public class ListMember {
}
+ /**
+ * 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.
+ * @param list
+ * @param user
+ * @param state
+ * @return
+ * @throws SQLException
+ */
public static ListMember create(MailingList list, User user, int state) throws SQLException {
String token = null;
if ((state & STATE_AWAITING_CONFIRMATION) > 0){
@@ -62,6 +94,10 @@ public class ListMember {
return new ListMember(list.email(),user.email(),state,token).save();
}
+ /**
+ * create the table for ListMember objects
+ * @throws SQLException
+ */
public static void createTable() throws SQLException {
var sql = new StringBuilder()
.append("CREATE TABLE ").append(TABLE_NAME)
@@ -74,11 +110,35 @@ public class ListMember {
Database.open().query(sql).compile().run();
}
+ /**
+ * create a new ListMember object from a ResultSet
+ * @param rs
+ * @return
+ * @throws SQLException
+ */
+ public static ListMember from(ResultSet rs) throws SQLException {
+ return new ListMember(
+ rs.getString(LIST_EMAIL),
+ rs.getString(USER_EMAIL),
+ rs.getInt(STATE),
+ rs.getString(TOKEN));
+ }
+
+ /**
+ * test, if the current object has a given state
+ * @param testState
+ * @return
+ */
public boolean hasState(int testState) {
return (state & testState) > 0;
}
+ /**
+ * return a set of list emails of MailingLists owned by the given user
+ * @param user
+ * @return
+ */
public static Set listsOwnedBy(User user) {
var list = new HashSet();
try {
@@ -92,6 +152,13 @@ public class ListMember {
return list;
}
+ /**
+ * load the list member specified by a MailingList and as User object
+ * @param list
+ * @param user
+ * @return
+ * @throws SQLException
+ */
public static ListMember load(MailingList list,User user) throws SQLException {
var rs = Database
.open()
@@ -101,19 +168,21 @@ public class ListMember {
.compile()
.exec();
try {
- if (rs.next()) {
- return new ListMember(rs.getString(LIST_EMAIL),
- rs.getString(USER_EMAIL),
- rs.getInt(STATE),
- rs.getString(TOKEN));
- }
+ if (rs.next()) return ListMember.from(rs);
} finally {
rs.close();
}
return null;
}
+ /**
+ * return a map of User → State for a given MailingList
+ * @param listEmail
+ * @return
+ * @throws SQLException
+ */
public static Map of(String listEmail) throws SQLException {
+ // Step 1: create mal USER_EMAIL → STATE for MailingList
var rs = Database.open()
.select(TABLE_NAME)
.where(LIST_EMAIL,listEmail)
@@ -121,6 +190,8 @@ public class ListMember {
.exec();
var temp = new HashMap();
while (rs.next()) temp.put(rs.getString(USER_EMAIL),rs.getInt(STATE));
+ rs.close();
+ // Step 2: map user emails to users
var result = new HashMap();
User.loadAll(temp.keySet())
.stream()
@@ -128,6 +199,27 @@ public class ListMember {
return result;
}
+ /**
+ * Save the current ListMember object to the database
+ * @return
+ * @throws SQLException
+ */
+ private ListMember save() throws SQLException {
+ var req = Database.open()
+ .insertInto(TABLE_NAME)
+ .set(LIST_EMAIL,listEmail)
+ .set(USER_EMAIL,userEmail)
+ .set(STATE,state);
+ if (token != null) req.set(TOKEN,token);
+ req.compile().run();
+ return this;
+ }
+
+ /**
+ * convert state flag to readable text
+ * @param state
+ * @return
+ */
public static String stateText(int state) {
var words = new ArrayList();
if ((state & STATE_OWNER) > 0) words.add("owner");
@@ -136,20 +228,20 @@ public class ListMember {
return String.join(", ",words);
}
- private ListMember save() throws SQLException {
- var vals = new HashMap();
- vals.put(LIST_EMAIL,listEmail);
- vals.put(USER_EMAIL,userEmail);
- vals.put(STATE,state);
- if (token != null) vals.put(TOKEN,token);
- Database.open().insertInto(TABLE_NAME).values(vals).compile().run();
- return this;
- }
-
+ /**
+ * get the token of the current list member
+ * @return
+ */
public String token() {
return token;
}
+ /**
+ * unsubscribe a list member
+ * @param list
+ * @param user
+ * @throws SQLException
+ */
public static void unsubscribe(MailingList list, User user) throws SQLException {
var db = Database.open();
var rs = db.select(TABLE_NAME)
@@ -158,21 +250,9 @@ public class ListMember {
.compile()
.exec();
while (rs.next()){
- int state = Util.unset(rs.getInt(STATE),STATE_SUBSCRIBER,STATE_AWAITING_CONFIRMATION);
- if (state < 1) { // drop entry
- db.deleteFrom(TABLE_NAME)
- .where(LIST_EMAIL,list.email())
- .where(USER_EMAIL,user.email())
- .compile()
- .run();
- } else { // update entry: whitdraw subscription
- db.update(TABLE_NAME)
- .set(STATE,state)
- .where(LIST_EMAIL,list.email())
- .where(USER_EMAIL,user.email())
- .compile()
- .run();
- }
+ int state = Util.unset(rs.getInt(STATE),STATE_SUBSCRIBER,STATE_AWAITING_CONFIRMATION); // drop subscription and awaiting flags
+ var req = state < 1 ? db.deleteFrom(TABLE_NAME) : db.update(TABLE_NAME).set(STATE,state).set(TOKEN,null);
+ req.where(LIST_EMAIL,list.email()).where(USER_EMAIL,user.email()).compile().run();
}
}
}