sorted methods alphabetically
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -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 {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,92 +28,16 @@ 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 MessageDigest getSha256() {
|
||||
try {
|
||||
return MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String sha256(String s) {
|
||||
byte[] bytes = SHA256.digest(s.getBytes(StandardCharsets.UTF_8));
|
||||
return hex(bytes);
|
||||
}
|
||||
|
||||
private static String hex(byte[] bytes) {
|
||||
StringBuffer buf = new StringBuffer(bytes.length*2);
|
||||
for (var byt : bytes) buf.append(hex(byt));
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String hex(int b){
|
||||
int lower = b & 0x0F;
|
||||
int upper = (b & 0xF0) >> 4;
|
||||
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 boolean simplePassword(String pass) {
|
||||
if (pass.length() < 6) return true;
|
||||
if (pass.length() < 8){
|
||||
for (int i=0; i<pass.length();i++){
|
||||
if (!Character.isLetterOrDigit(pass.charAt(i))) return false; // password contains special character
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (pass.length() < 10){
|
||||
var digit = false;
|
||||
var letter = false;
|
||||
for (int i=0; i<pass.length();i++){
|
||||
char c = pass.charAt(i);
|
||||
if (!Character.isLetterOrDigit(c)) return false; // password contains special character
|
||||
digit |= Character.isDigit(c);
|
||||
letter |= Character.isLetter(c);
|
||||
if (letter && digit) return false; // password contains letters and digits
|
||||
}
|
||||
return true;
|
||||
}
|
||||
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 boolean getCheckbox(HttpServletRequest req, String key) {
|
||||
return "on".equals(req.getParameter(key));
|
||||
}
|
||||
|
||||
public static MailingList getMailingList(HttpServletRequest req) {
|
||||
@@ -122,8 +46,22 @@ public class Util {
|
||||
return MailingList.load(listEmail);
|
||||
}
|
||||
|
||||
public static boolean getCheckbox(HttpServletRequest req, String key) {
|
||||
return "on".equals(req.getParameter(key));
|
||||
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");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,16 +95,75 @@ public class Util {
|
||||
if (s != null) return s;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String dropEmail(String tx) {
|
||||
return tx.replaceAll( "[.\\-\\w]+@[.\\-\\w]+", "[email_removed]");
|
||||
public static User getUser(HttpServletRequest req) {
|
||||
var o = req.getSession().getAttribute(USER);
|
||||
return o instanceof User ? (User) o : null;
|
||||
}
|
||||
|
||||
public static <T> T getNullable(ResultSet rs, String colName) throws SQLException {
|
||||
final T val = (T) rs.getObject(colName);
|
||||
return rs.wasNull() ? null : val;
|
||||
private static String hex(byte[] bytes) {
|
||||
StringBuffer buf = new StringBuffer(bytes.length*2);
|
||||
for (var byt : bytes) buf.append(hex(byt));
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String hex(int b){
|
||||
int lower = b & 0x0F;
|
||||
int upper = (b & 0xF0) >> 4;
|
||||
return (char)(upper < 10 ? '0'+upper : 'A'+upper-10)+""+(char)(lower < 10 ? '0'+lower : 'A'+lower-10);
|
||||
}
|
||||
|
||||
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){
|
||||
for (int i=0; i<pass.length();i++){
|
||||
if (!Character.isLetterOrDigit(pass.charAt(i))) return false; // password contains special character
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (pass.length() < 10){
|
||||
var digit = false;
|
||||
var letter = false;
|
||||
for (int i=0; i<pass.length();i++){
|
||||
char c = pass.charAt(i);
|
||||
if (!Character.isLetterOrDigit(c)) return false; // password contains special character
|
||||
digit |= Character.isDigit(c);
|
||||
letter |= Character.isLetter(c);
|
||||
if (letter && digit) return false; // password contains letters and digits
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String t(String tx, Object ... fills){
|
||||
return Translation.get(Application.class,tx,fills);
|
||||
}
|
||||
|
||||
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 int unset(int value, int...flags) {
|
||||
for (int flag : flags){
|
||||
if ((value & flag) > 0) value ^= flag;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
@@ -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 {
|
||||
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)
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Heartbeat doStop() {
|
||||
stopped = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public ImapClient(String host, int port, String username, String password, String folderName,ProblemListener listener) {
|
||||
@@ -165,27 +165,15 @@ public class ImapClient {
|
||||
inbox.expunge();
|
||||
}
|
||||
|
||||
public String folderName(){
|
||||
return folderName;
|
||||
}
|
||||
|
||||
|
||||
public String host(){
|
||||
return host;
|
||||
}
|
||||
|
||||
public String username(){
|
||||
return username;
|
||||
}
|
||||
|
||||
public String password(){
|
||||
return password;
|
||||
}
|
||||
|
||||
public int port(){
|
||||
return port;
|
||||
}
|
||||
|
||||
public String folderName(){
|
||||
return folderName;
|
||||
}
|
||||
|
||||
public ImapClient move(Message message, String destinationFolder) throws MessagingException {
|
||||
if (listeningThread == null || listeningThread.stopped) throw new IllegalStateException("IMAP client not connected!");
|
||||
var source = message.getFolder();
|
||||
@@ -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 {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String username(){
|
||||
return username;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user