diff --git a/core/src/main/java/de/srsoftware/umbrella/core/Constants.java b/core/src/main/java/de/srsoftware/umbrella/core/Constants.java index 9297482..54948d0 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/Constants.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/Constants.java @@ -20,6 +20,7 @@ public class Constants { public static final String COMMENT = "comment"; public static final String COMPANY = "company"; public static final String COMPANY_ID = "company_id"; + public static final String CONTENT = "content"; public static final String CONTENT_TYPE = "Content-Type"; public static final String CUSTOMER_NUMBER_PREFIX = "customer_number_prefix"; @@ -179,5 +180,7 @@ public class Constants { public static final String UTF8 = UTF_8.displayName(); public static final String VALUE = "value"; + public static final String VERSION = "version"; + public static final String VERSIONS = "versions"; } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/Paths.java b/core/src/main/java/de/srsoftware/umbrella/core/Paths.java index 1254d23..2281e9e 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/Paths.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/Paths.java @@ -11,6 +11,7 @@ public class Paths { public static final String LEGACY = "legacy"; public static final String LIST = "list"; public static final String LOGOUT = "logout"; + public static final String PAGE = "page"; public static final String SEARCH = "search"; public static final String SERVICE = "service"; public static final String SETTINGS = "settings"; diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java b/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java index 280d0eb..a42d6c0 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java @@ -2,20 +2,57 @@ package de.srsoftware.umbrella.core.model; import de.srsoftware.tools.Mappable; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; -import static de.srsoftware.umbrella.core.Constants.ID; +import static de.srsoftware.umbrella.core.Constants.*; +import static de.srsoftware.umbrella.core.Util.markdown; public class WikiPage implements Mappable { - private final long id; + private final String id; + private final int version; + private final List versions = new ArrayList<>(); + private final Map members = new HashMap<>(); + private final String content; - public WikiPage(long id){ + public WikiPage(String id, int version, String content) { this.id = id; + this.version = version; + this.content = content; + } + + public String id(){ + return id; + } + + public Map members(){ + return members; + } + + public static WikiPage of(ResultSet rs) throws SQLException { + return new WikiPage(rs.getString(ID),rs.getInt(VERSION),rs.getString(CONTENT)); } @Override public Map toMap() { - return Map.of(ID,id); + var memberMap = new HashMap>(); + for (var entry : members.entrySet()) memberMap.put(entry.getKey(),entry.getValue().toMap()); + + return Map.of( + ID,id, + CONTENT,Map.of(SOURCE,content,RENDERED,markdown(content)), + MEMBERS,memberMap, + VERSION,version, + VERSIONS,versions + ); + } + + public List versions(){ + return versions; } } diff --git a/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java b/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java index 7fac14b..7aece72 100644 --- a/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java +++ b/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java @@ -16,7 +16,6 @@ public class Constants { public static final String CONFIG_DATABASE = "umbrella.modules.document.database"; public static final String CONFIG_TEMPLATES = "umbrella.modules.document.templates"; public static final String CONTACTS = "contacts"; - public static final String CONTENT = "content"; public static final String CONTENT_DISPOSITION = "Content-Disposition"; public static final String CUSTOMERS = "customers"; diff --git a/frontend/src/routes/wiki/View.svelte b/frontend/src/routes/wiki/View.svelte index a13b288..6450ddc 100644 --- a/frontend/src/routes/wiki/View.svelte +++ b/frontend/src/routes/wiki/View.svelte @@ -20,9 +20,17 @@ } } + async function onSet(newVal){ + console.log('TODO: implement patch',newVal); + return true; + } + onMount(loadPage);

{id}

{#if error} {error} +{/if} +{#if page} + {/if} \ No newline at end of file diff --git a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java index 19a54ec..249c733 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java @@ -134,7 +134,7 @@ public class UserModule extends BaseHandler implements UserService { @Override public Map list(Integer start, Integer limit, Collection ids) throws UmbrellaException { - return users.list(0,null,ids); + return users.list(start, limit, ids); } public UmbrellaUser load(Session session) throws UmbrellaException{ diff --git a/wiki/src/main/java/de/srsoftware/umbrella/wiki/Constants.java b/wiki/src/main/java/de/srsoftware/umbrella/wiki/Constants.java index a80dbb7..bebf0f1 100644 --- a/wiki/src/main/java/de/srsoftware/umbrella/wiki/Constants.java +++ b/wiki/src/main/java/de/srsoftware/umbrella/wiki/Constants.java @@ -5,10 +5,8 @@ public class Constants { private Constants(){} public static final String CONFIG_DATABASE = "umbrella.modules.wiki.database"; - public static final String CONTENT = "content"; public static final String PAGE_ID = "page_id"; public static final String PERMISSIONS = "permissions"; public static final String TABLE_PAGES = "pages"; public static final String TABLE_PAGES_USERS = "page_users"; - public static final String VERSION = "version"; } diff --git a/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java b/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java index 0693f9d..1bae88b 100644 --- a/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java +++ b/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java @@ -2,15 +2,20 @@ package de.srsoftware.umbrella.wiki; import de.srsoftware.tools.jdbc.Condition; import de.srsoftware.umbrella.core.BaseDb; +import de.srsoftware.umbrella.core.model.Hash; +import de.srsoftware.umbrella.core.model.Permission; +import de.srsoftware.umbrella.core.model.WikiPage; import java.sql.Connection; import java.sql.SQLException; import java.util.*; +import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL; import static de.srsoftware.tools.jdbc.Query.select; import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.ERROR_FAILED_CREATE_TABLE; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException; +import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.notFound; import static de.srsoftware.umbrella.wiki.Constants.*; import static java.lang.System.Logger.Level.ERROR; import static java.text.MessageFormat.format; @@ -71,4 +76,42 @@ public class SqliteDb extends BaseDb implements WikiDb { throw databaseException("Failed to list wiki articles for user {0}",userId); } } + + @Override + public WikiPage load(String id) { + try { + var rs = select(ALL).from(TABLE_PAGES).where(ID,Condition.equal(id)).sort(VERSION).limit(1).exec(db); + WikiPage page = null; + if (rs.next()) page = WikiPage.of(rs); + rs.close(); + if (page == null) throw notFound("Failed to load wiki page \"{0}\" from databse!",id); + rs = select(VERSION).from(TABLE_PAGES).where(ID,Condition.equal(id)).sort(VERSION).exec(db); + var versions = page.versions(); + while (rs.next()) versions.add(rs.getInt(VERSION)); + rs.close(); + return page; + } catch (SQLException e) { + throw databaseException("Failed to load wiki page \"{0}\" from database!",id); + } + } + + @Override + public Map loadMembers(WikiPage page) { + try { + var map = new HashMap(); + var rs = select(ALL).from(TABLE_PAGES_USERS).where(PAGE_ID,Condition.equal(page.id())).exec(db); + while (rs.next()){ + var permission = switch (rs.getInt(PERMISSIONS)){ + case 1 -> Permission.READ_ONLY; + case 2, 3 -> Permission.EDIT; + default -> null; + }; + if (permission != null) map.put(rs.getLong(USER_ID),permission); + } + rs.close(); + return map; + } catch (SQLException e) { + throw databaseException("Failed to load members of \"{0}\" from database!",page.id()); + } + } } \ No newline at end of file diff --git a/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiDb.java b/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiDb.java index e9f5588..7ca9ac4 100644 --- a/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiDb.java +++ b/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiDb.java @@ -2,9 +2,17 @@ package de.srsoftware.umbrella.wiki; +import de.srsoftware.umbrella.core.model.Permission; +import de.srsoftware.umbrella.core.model.WikiPage; + import java.util.List; +import java.util.Map; public interface WikiDb { List listUserPages(long userId); + + WikiPage load(String id); + + Map loadMembers(WikiPage page); } diff --git a/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiModule.java b/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiModule.java index 474064e..1735353 100644 --- a/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiModule.java +++ b/wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiModule.java @@ -8,16 +8,20 @@ import de.srsoftware.umbrella.core.BaseHandler; import de.srsoftware.umbrella.core.ModuleRegistry; import de.srsoftware.umbrella.core.api.WikiService; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; +import de.srsoftware.umbrella.core.model.Member; import de.srsoftware.umbrella.core.model.Token; import de.srsoftware.umbrella.core.model.UmbrellaUser; +import de.srsoftware.umbrella.core.model.WikiPage; import java.io.IOException; import java.util.Optional; import static de.srsoftware.umbrella.core.ConnectionProvider.connect; +import static de.srsoftware.umbrella.core.Paths.PAGE; +import static de.srsoftware.umbrella.core.Paths.VIEW; import static de.srsoftware.umbrella.core.Util.mapValues; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException; -import static de.srsoftware.umbrella.wiki.Constants.CONFIG_DATABASE; +import static de.srsoftware.umbrella.wiki.Constants.*; public class WikiModule extends BaseHandler implements WikiService { private final WikiDb wikiDb; @@ -39,6 +43,7 @@ public class WikiModule extends BaseHandler implements WikiService { var head = path.pop(); return switch (head) { case null -> getUserPages(user.get(),ex); + case PAGE -> getPage(path, user.get(), ex); default -> super.doGet(path,ex); }; } catch (UmbrellaException e){ @@ -46,6 +51,26 @@ public class WikiModule extends BaseHandler implements WikiService { } } + private boolean getPage(Path path, UmbrellaUser user, HttpExchange ex) throws IOException { + var id = path.pop(); + if (id == null) throw missingFieldException(PAGE_ID); + return sendContent(ex, loadMembers(wikiDb.load(id))); + } + + + private WikiPage loadMembers(WikiPage page) { + var members = wikiDb.loadMembers(page); + var users = userService().list(null,null,members.keySet()); + var pageMembers = page.members(); + for (var entry : members.entrySet()){ + var userId = entry.getKey(); + var permission = entry.getValue(); + var user = users.get(userId); + pageMembers.put(userId,new Member(user,permission)); + } + return page; + } + private boolean getUserPages(UmbrellaUser user, HttpExchange ex) throws IOException { var pageList = wikiDb.listUserPages(user.id()); return sendContent(ex,pageList);