|
|
|
|
@@ -1,8 +1,10 @@
|
|
|
|
|
/* © SRSoftware 2025 */
|
|
|
|
|
package de.srsoftware.umbrella.bookmarks;
|
|
|
|
|
|
|
|
|
|
import static de.srsoftware.umbrella.messagebus.events.Event.EventType;
|
|
|
|
|
import static de.srsoftware.umbrella.bookmarks.Constants.*;
|
|
|
|
|
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
|
|
|
|
import static de.srsoftware.umbrella.core.ModuleRegistry.tagService;
|
|
|
|
|
import static de.srsoftware.umbrella.core.Util.mapValues;
|
|
|
|
|
import static de.srsoftware.umbrella.core.constants.Field.*;
|
|
|
|
|
import static de.srsoftware.umbrella.core.constants.Field.TAGS;
|
|
|
|
|
@@ -10,7 +12,11 @@ import static de.srsoftware.umbrella.core.constants.Module.BOOKMARK;
|
|
|
|
|
import static de.srsoftware.umbrella.core.constants.Path.LIST;
|
|
|
|
|
import static de.srsoftware.umbrella.core.constants.Path.SEARCH;
|
|
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
|
|
|
|
import static de.srsoftware.umbrella.messagebus.MessageBus.messageBus;
|
|
|
|
|
import static de.srsoftware.umbrella.messagebus.events.Event.EventType.CREATE;
|
|
|
|
|
import static de.srsoftware.umbrella.messagebus.events.Event.EventType.UPDATE;
|
|
|
|
|
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
|
|
|
|
import static java.net.HttpURLConnection.HTTP_OK;
|
|
|
|
|
|
|
|
|
|
import com.sun.net.httpserver.HttpExchange;
|
|
|
|
|
import de.srsoftware.configuration.Configuration;
|
|
|
|
|
@@ -19,14 +25,18 @@ import de.srsoftware.tools.SessionToken;
|
|
|
|
|
import de.srsoftware.umbrella.core.BaseHandler;
|
|
|
|
|
import de.srsoftware.umbrella.core.ModuleRegistry;
|
|
|
|
|
import de.srsoftware.umbrella.core.api.BookmarkService;
|
|
|
|
|
import de.srsoftware.umbrella.core.constants.Text;
|
|
|
|
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
|
|
|
|
import de.srsoftware.umbrella.core.model.Token;
|
|
|
|
|
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
|
|
|
|
|
|
|
|
|
import java.awt.print.Book;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Optional;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
import de.srsoftware.umbrella.messagebus.events.BookmarkEvent;
|
|
|
|
|
import de.srsoftware.umbrella.messagebus.events.Event;
|
|
|
|
|
import de.srsoftware.umbrella.messagebus.events.TaskEvent;
|
|
|
|
|
import org.json.JSONArray;
|
|
|
|
|
|
|
|
|
|
public class BookmarkApi extends BaseHandler implements BookmarkService {
|
|
|
|
|
@@ -39,6 +49,30 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
|
|
|
|
|
ModuleRegistry.add(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean deleteBookmark(UmbrellaUser user, HttpExchange ex, long urlId) throws IOException {
|
|
|
|
|
var bookmark = db.load(urlId,user.id());
|
|
|
|
|
db.remove(user, bookmark);
|
|
|
|
|
return sendEmptyResponse(HTTP_OK,ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean doDelete(Path path, HttpExchange ex) throws IOException {
|
|
|
|
|
addCors(ex);
|
|
|
|
|
try {
|
|
|
|
|
Optional<Token> token = SessionToken.from(ex).map(Token::of);
|
|
|
|
|
var user = ModuleRegistry.userService().loadUser(token);
|
|
|
|
|
if (user.isEmpty()) return unauthorized(ex);
|
|
|
|
|
var head = path.pop();
|
|
|
|
|
if (head == null) throw missingField(ID);
|
|
|
|
|
var id = Long.parseLong(head);
|
|
|
|
|
return deleteBookmark(user.get(),ex,id);
|
|
|
|
|
} catch (NumberFormatException e){
|
|
|
|
|
throw invalidField(ID, Text.NUMBER);
|
|
|
|
|
} catch (UmbrellaException e){
|
|
|
|
|
return send(ex,e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
|
|
|
|
addCors(ex);
|
|
|
|
|
@@ -51,21 +85,33 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
|
|
|
|
|
case LIST -> getUserBookmarks(user.get(),ex);
|
|
|
|
|
case null -> super.doPost(path,ex);
|
|
|
|
|
default -> {
|
|
|
|
|
var id = Long.parseLong(head);
|
|
|
|
|
yield getBookmark(user.get(),id,ex);
|
|
|
|
|
var urlId = Long.parseLong(head);
|
|
|
|
|
yield getBookmark(user.get(),urlId,ex);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
} catch (NumberFormatException e){
|
|
|
|
|
return sendContent(ex,HTTP_BAD_REQUEST,"Invalid project id");
|
|
|
|
|
throw invalidField(ID, Text.NUMBER);
|
|
|
|
|
} catch (UmbrellaException e){
|
|
|
|
|
return send(ex,e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean getBookmark(UmbrellaUser user, long id, HttpExchange ex) throws IOException {
|
|
|
|
|
var bookmark = db.load(id,user.id());
|
|
|
|
|
ModuleRegistry.tagService().getTags(BOOKMARK, id, user).forEach(bookmark.tags()::add);
|
|
|
|
|
return sendContent(ex,bookmark);
|
|
|
|
|
@Override
|
|
|
|
|
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
|
|
|
|
|
addCors(ex);
|
|
|
|
|
try {
|
|
|
|
|
Optional<Token> token = SessionToken.from(ex).map(Token::of);
|
|
|
|
|
var user = ModuleRegistry.userService().loadUser(token);
|
|
|
|
|
if (user.isEmpty()) return unauthorized(ex);
|
|
|
|
|
var head = path.pop();
|
|
|
|
|
if (head == null) throw missingField(ID);
|
|
|
|
|
var id = Long.parseLong(head);
|
|
|
|
|
return patchBookmark(user.get(),ex,id);
|
|
|
|
|
} catch (NumberFormatException e){
|
|
|
|
|
throw invalidField(ID, Text.NUMBER);
|
|
|
|
|
} catch (UmbrellaException e){
|
|
|
|
|
return send(ex,e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@@ -93,6 +139,12 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
|
|
|
|
|
return db.findUrls(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean getBookmark(UmbrellaUser user, long urlId, HttpExchange ex) throws IOException {
|
|
|
|
|
var bookmark = db.load(urlId,user.id());
|
|
|
|
|
tagService().getTags(BOOKMARK, urlId, user).forEach(bookmark.tags()::add);
|
|
|
|
|
return sendContent(ex,bookmark);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean getUserBookmarks(UmbrellaUser user, HttpExchange ex) throws IOException {
|
|
|
|
|
var param = queryParam(ex);
|
|
|
|
|
long offset = switch (param.get(OFFSET)){
|
|
|
|
|
@@ -110,6 +162,23 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
|
|
|
|
|
return sendContent(ex,mapValues(bookmarks));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean patchBookmark(UmbrellaUser user, HttpExchange ex, long urlId) throws IOException {
|
|
|
|
|
var bookmark = db.load(urlId,user.id());
|
|
|
|
|
var tags = tagService().getTags(BOOKMARK,urlId,user);
|
|
|
|
|
var json = json(ex);
|
|
|
|
|
var comment = bookmark.comment();
|
|
|
|
|
var url = bookmark.url();
|
|
|
|
|
if (json.has(COMMENT) && json.get(COMMENT) instanceof String c) comment = c;
|
|
|
|
|
if (json.has(URL) && json.get(URL) instanceof String u) url = u;
|
|
|
|
|
var newBookmark = db.save(url,comment, List.of(user.id()),bookmark.timestamp());
|
|
|
|
|
if (newBookmark.urlId() != urlId) {
|
|
|
|
|
tagService().save(BOOKMARK,newBookmark.urlId(),List.of(user.id()),tags);
|
|
|
|
|
db.remove(user, bookmark);
|
|
|
|
|
//messageBus().dispatch(new BookmarkEvent(user,newBookmark,CREATE));
|
|
|
|
|
} else messageBus().dispatch(new BookmarkEvent(user,newBookmark,UPDATE));
|
|
|
|
|
return sendContent(ex,newBookmark);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean postBookmark(UmbrellaUser user, HttpExchange ex) throws IOException {
|
|
|
|
|
var json = json(ex);
|
|
|
|
|
if (!(json.has(URL) && json.get(URL) instanceof String url)) throw missingField(URL);
|
|
|
|
|
@@ -123,10 +192,11 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var bookmark = db.save(url,comment, userList);
|
|
|
|
|
messageBus().dispatch(new BookmarkEvent(user,bookmark,CREATE));
|
|
|
|
|
|
|
|
|
|
if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray tagList){
|
|
|
|
|
var list = tagList.toList().stream().map(Object::toString).toList();
|
|
|
|
|
ModuleRegistry.tagService().save(BOOKMARK,bookmark.urlId(), userList, list);
|
|
|
|
|
tagService().save(BOOKMARK,bookmark.urlId(), userList, list);
|
|
|
|
|
}
|
|
|
|
|
return sendContent(ex,bookmark);
|
|
|
|
|
}
|
|
|
|
|
|