|
|
|
@ -4,6 +4,7 @@ package de.srsoftware.umbrella.project; |
|
|
|
import static de.srsoftware.umbrella.core.ConnectionProvider.connect; |
|
|
|
import static de.srsoftware.umbrella.core.ConnectionProvider.connect; |
|
|
|
import static de.srsoftware.umbrella.core.Constants.*; |
|
|
|
import static de.srsoftware.umbrella.core.Constants.*; |
|
|
|
import static de.srsoftware.umbrella.core.Paths.LIST; |
|
|
|
import static de.srsoftware.umbrella.core.Paths.LIST; |
|
|
|
|
|
|
|
import static de.srsoftware.umbrella.core.Paths.SEARCH; |
|
|
|
import static de.srsoftware.umbrella.core.Util.mapValues; |
|
|
|
import static de.srsoftware.umbrella.core.Util.mapValues; |
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; |
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; |
|
|
|
import static de.srsoftware.umbrella.core.model.Permission.*; |
|
|
|
import static de.srsoftware.umbrella.core.model.Permission.*; |
|
|
|
@ -29,12 +30,12 @@ import org.json.JSONObject; |
|
|
|
|
|
|
|
|
|
|
|
public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
|
|
|
|
|
|
|
|
private final ProjectDb projects; |
|
|
|
private final ProjectDb projectDb; |
|
|
|
|
|
|
|
|
|
|
|
public ProjectModule(ModuleRegistry registry, Configuration config) throws UmbrellaException { |
|
|
|
public ProjectModule(ModuleRegistry registry, Configuration config) throws UmbrellaException { |
|
|
|
super(registry); |
|
|
|
super(registry); |
|
|
|
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE)); |
|
|
|
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE)); |
|
|
|
projects = new SqliteDb(connect(dbFile)); |
|
|
|
projectDb = new SqliteDb(connect(dbFile)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void addMember(Project project, long userId) { |
|
|
|
private void addMember(Project project, long userId) { |
|
|
|
@ -53,7 +54,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
if (user.isEmpty()) return unauthorized(ex); |
|
|
|
if (user.isEmpty()) return unauthorized(ex); |
|
|
|
var head = path.pop(); |
|
|
|
var head = path.pop(); |
|
|
|
return switch (head) { |
|
|
|
return switch (head) { |
|
|
|
case null -> postProject(ex,user.get()); |
|
|
|
case null -> super.doGet(path, ex); |
|
|
|
default -> { |
|
|
|
default -> { |
|
|
|
var projectId = Long.parseLong(head); |
|
|
|
var projectId = Long.parseLong(head); |
|
|
|
head = path.pop(); |
|
|
|
head = path.pop(); |
|
|
|
@ -82,7 +83,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
head = path.pop(); |
|
|
|
head = path.pop(); |
|
|
|
yield switch (head){ |
|
|
|
yield switch (head){ |
|
|
|
case null -> patchProject(ex,projectId,user.get()); |
|
|
|
case null -> patchProject(ex,projectId,user.get()); |
|
|
|
default -> super.doGet(path,ex); |
|
|
|
default -> super.doPatch(path,ex); |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
@ -101,6 +102,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
var head = path.pop(); |
|
|
|
var head = path.pop(); |
|
|
|
return switch (head) { |
|
|
|
return switch (head) { |
|
|
|
case LIST -> postProjectList(ex, user.get()); |
|
|
|
case LIST -> postProjectList(ex, user.get()); |
|
|
|
|
|
|
|
case SEARCH -> postSearch(user.get(),ex); |
|
|
|
case null -> postProject(ex, user.get()); |
|
|
|
case null -> postProject(ex, user.get()); |
|
|
|
default -> { |
|
|
|
default -> { |
|
|
|
var projectId = Long.parseLong(head); |
|
|
|
var projectId = Long.parseLong(head); |
|
|
|
@ -120,12 +122,12 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
|
|
|
|
|
|
|
|
private void dropMember(Project project, long userId) { |
|
|
|
private void dropMember(Project project, long userId) { |
|
|
|
if (project.members().get(userId).permission() == OWNER) throw forbidden("You may not remove the owner of the project"); |
|
|
|
if (project.members().get(userId).permission() == OWNER) throw forbidden("You may not remove the owner of the project"); |
|
|
|
projects.dropMember(project.id(),userId); |
|
|
|
projectDb.dropMember(project.id(),userId); |
|
|
|
project.members().remove(userId); |
|
|
|
project.members().remove(userId); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private boolean getProject(HttpExchange ex, long projectId, UmbrellaUser user) throws IOException, UmbrellaException { |
|
|
|
private boolean getProject(HttpExchange ex, long projectId, UmbrellaUser user) throws IOException, UmbrellaException { |
|
|
|
var project = loadMembers(projects.load(projectId)); |
|
|
|
var project = loadMembers(projectDb.load(projectId)); |
|
|
|
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name()); |
|
|
|
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name()); |
|
|
|
var map = project.toMap(); |
|
|
|
var map = project.toMap(); |
|
|
|
project.companyId().map(companyService()::get).map(Company::toMap).ifPresent(data -> map.put(COMPANY,data)); |
|
|
|
project.companyId().map(companyService()::get).map(Company::toMap).ifPresent(data -> map.put(COMPANY,data)); |
|
|
|
@ -133,7 +135,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Map<Long, Project> listCompanyProjects(long companyId, boolean includeClosed) throws UmbrellaException { |
|
|
|
public Map<Long, Project> listCompanyProjects(long companyId, boolean includeClosed) throws UmbrellaException { |
|
|
|
var projectList = projects.ofCompany(companyId, includeClosed); |
|
|
|
var projectList = projectDb.ofCompany(companyId, includeClosed); |
|
|
|
loadMembers(projectList.values()); |
|
|
|
loadMembers(projectList.values()); |
|
|
|
return projectList; |
|
|
|
return projectList; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -147,7 +149,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Map<Long, Project> listUserProjects(long userId, boolean includeClosed) throws UmbrellaException { |
|
|
|
public Map<Long, Project> listUserProjects(long userId, boolean includeClosed) throws UmbrellaException { |
|
|
|
var projectMap = projects.ofUser(userId, includeClosed); |
|
|
|
var projectMap = projectDb.ofUser(userId, includeClosed); |
|
|
|
loadMembers(projectMap.values()); |
|
|
|
loadMembers(projectMap.values()); |
|
|
|
return projectMap; |
|
|
|
return projectMap; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -159,14 +161,14 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Project load(long projectId) { |
|
|
|
public Project load(long projectId) { |
|
|
|
return projects.load(projectId); |
|
|
|
return projectDb.load(projectId); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Collection<Project> loadMembers(Collection<Project> projectList) { |
|
|
|
public Collection<Project> loadMembers(Collection<Project> projectList) { |
|
|
|
var userMap = new HashMap<Long,UmbrellaUser>(); |
|
|
|
var userMap = new HashMap<Long,UmbrellaUser>(); |
|
|
|
for (var project : projectList){ |
|
|
|
for (var project : projectList){ |
|
|
|
for (var entry : projects.getMembers(project).entrySet()){ |
|
|
|
for (var entry : projectDb.getMembers(project).entrySet()){ |
|
|
|
var userId = entry.getKey(); |
|
|
|
var userId = entry.getKey(); |
|
|
|
var permission = entry.getValue(); |
|
|
|
var permission = entry.getValue(); |
|
|
|
var user = userMap.computeIfAbsent(userId,k -> userService().loadUser(userId)); |
|
|
|
var user = userMap.computeIfAbsent(userId,k -> userService().loadUser(userId)); |
|
|
|
@ -199,14 +201,14 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private boolean patchProject(HttpExchange ex, long projectId, UmbrellaUser user) throws IOException, UmbrellaException { |
|
|
|
private boolean patchProject(HttpExchange ex, long projectId, UmbrellaUser user) throws IOException, UmbrellaException { |
|
|
|
var project = loadMembers(projects.load(projectId)); |
|
|
|
var project = loadMembers(projectDb.load(projectId)); |
|
|
|
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name()); |
|
|
|
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name()); |
|
|
|
var json = json(ex); |
|
|
|
var json = json(ex); |
|
|
|
if (json.has(DROP_MEMBER) && json.get(DROP_MEMBER) instanceof Number id) dropMember(project,id.longValue()); |
|
|
|
if (json.has(DROP_MEMBER) && json.get(DROP_MEMBER) instanceof Number id) dropMember(project,id.longValue()); |
|
|
|
if (json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject memberJson) patchMembers(project,memberJson); |
|
|
|
if (json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject memberJson) patchMembers(project,memberJson); |
|
|
|
if (json.has(NEW_MEMBER) && json.get(NEW_MEMBER) instanceof Number num) addMember(project,num.longValue()); |
|
|
|
if (json.has(NEW_MEMBER) && json.get(NEW_MEMBER) instanceof Number num) addMember(project,num.longValue()); |
|
|
|
|
|
|
|
|
|
|
|
projects.save(project.patch(json)); |
|
|
|
projectDb.save(project.patch(json)); |
|
|
|
return sendContent(ex,project.toMap()); |
|
|
|
return sendContent(ex,project.toMap()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -218,7 +220,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
if (!(json.has(CODE) && json.get(CODE) instanceof Number code)) throw missingFieldException(CODE); |
|
|
|
if (!(json.has(CODE) && json.get(CODE) instanceof Number code)) throw missingFieldException(CODE); |
|
|
|
if (!(json.has(NAME) && json.get(NAME) instanceof String name)) throw missingFieldException(NAME); |
|
|
|
if (!(json.has(NAME) && json.get(NAME) instanceof String name)) throw missingFieldException(NAME); |
|
|
|
var newState = new Status(name,code.intValue()); |
|
|
|
var newState = new Status(name,code.intValue()); |
|
|
|
return sendContent(ex,projects.save(projectId,newState)); |
|
|
|
return sendContent(ex, projectDb.save(projectId,newState)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private boolean postProject(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { |
|
|
|
private boolean postProject(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { |
|
|
|
@ -241,7 +243,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
} |
|
|
|
} |
|
|
|
var owner = Map.of(user.id(),new Member(user,OWNER)); |
|
|
|
var owner = Map.of(user.id(),new Member(user,OWNER)); |
|
|
|
var prj = new Project(0,name,description, OPEN.code(),companyId,showClosed, owner, PREDEFINED); |
|
|
|
var prj = new Project(0,name,description, OPEN.code(),companyId,showClosed, owner, PREDEFINED); |
|
|
|
prj = projects.save(prj); |
|
|
|
prj = projectDb.save(prj); |
|
|
|
|
|
|
|
|
|
|
|
if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){ |
|
|
|
if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){ |
|
|
|
var tagList = arr.toList().stream().filter(elem -> elem instanceof String).map(String.class::cast).toList(); |
|
|
|
var tagList = arr.toList().stream().filter(elem -> elem instanceof String).map(String.class::cast).toList(); |
|
|
|
@ -257,4 +259,14 @@ public class ProjectModule extends BaseHandler implements ProjectService { |
|
|
|
if (json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number companyId) return listCompanyProjects(ex, user, companyId.longValue()); |
|
|
|
if (json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number companyId) return listCompanyProjects(ex, user, companyId.longValue()); |
|
|
|
return listUserProjects(ex,user,showClosed); |
|
|
|
return listUserProjects(ex,user,showClosed); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean postSearch(UmbrellaUser user, HttpExchange ex) throws IOException { |
|
|
|
|
|
|
|
var json = json(ex); |
|
|
|
|
|
|
|
if (!(json.has(KEY) && json.get(KEY) instanceof String key)) throw missingFieldException(KEY); |
|
|
|
|
|
|
|
var keys = Arrays.asList(key.split(" ")); |
|
|
|
|
|
|
|
var fulltext = json.has(FULLTEXT) && json.get(FULLTEXT) instanceof Boolean val && val; |
|
|
|
|
|
|
|
var projects = projectDb.find(user.id(),keys,fulltext); |
|
|
|
|
|
|
|
return sendContent(ex,mapValues(projects)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |