package org.fenixedu.bennu.portal.api;
import java.util.Map.Entry;
import java.util.Optional;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.fenixedu.bennu.core.groups.Group;
import org.fenixedu.bennu.core.rest.BennuRestResource;
import org.fenixedu.bennu.portal.api.json.MenuItemAdapter;
import org.fenixedu.bennu.portal.domain.MenuContainer;
import org.fenixedu.bennu.portal.domain.MenuFunctionality;
import org.fenixedu.bennu.portal.domain.MenuItem;
import org.fenixedu.bennu.portal.model.Application;
import org.fenixedu.bennu.portal.model.ApplicationRegistry;
import org.fenixedu.bennu.portal.model.Functionality;
import org.fenixedu.commons.i18n.LocalizedString;
import pt.ist.fenixframework.Atomic;
import pt.ist.fenixframework.Atomic.TxMode;
import pt.ist.fenixframework.FenixFramework;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@Path("/bennu-portal/menu")
public class MenuResource extends BennuRestResource {
@Path("{oid}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public JsonElement getMenu(@PathParam("oid") final String menuOid) {
accessControl(Group.managers());
return viewMenu(getMenuItem(menuOid));
}
private JsonElement viewMenu(MenuItem menuItem) {
return view(menuItem, MenuItemAdapter.class);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JsonElement createMenu(final JsonElement jsonData) {
accessControl(Group.managers());
return viewMenu(create(jsonData, MenuContainer.class, MenuItemAdapter.class));
}
@POST
@Path("/sub-root")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JsonElement createSubRoot(final JsonObject json) {
accessControl(Group.managers());
String key = json.get("key").getAsString();
LocalizedString title = LocalizedString.fromJson(json.get("title"));
LocalizedString description = LocalizedString.fromJson(json.get("description"));
return viewMenu(createSubRoot(key, title, description));
}
@Atomic(mode = TxMode.WRITE)
private MenuItem createSubRoot(String key, LocalizedString title, LocalizedString description) {
return MenuContainer.createSubRoot(key, title, description);
}
@PUT
@Path("{oid}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JsonElement updateMenu(final JsonElement jsonData, @PathParam("oid") final String oid) {
accessControl(Group.managers());
return viewMenu(update(jsonData, getMenuItem(oid), MenuItemAdapter.class));
}
@Path("{oid}")
@DELETE
@Produces(MediaType.APPLICATION_JSON)
public JsonElement deleteMenu(@PathParam("oid") final String menuOid) {
accessControl(Group.managers());
final MenuItem menuItem = getMenuItem(menuOid);
final JsonElement rsp = viewMenu(menuItem);
menuItem.delete();
return rsp;
}
@POST
@Path("/order")
@Consumes(MediaType.APPLICATION_JSON)
public Response reorderItems(final JsonObject object) {
accessControl(Group.managers());
reorder(object);
return ok();
}
@Atomic
private void reorder(JsonObject object) {
for (Entry<String, JsonElement> entry : object.entrySet()) {
MenuItem item = FenixFramework.getDomainObject(entry.getKey());
item.setOrd(entry.getValue().getAsInt());
}
}
@GET
@Path("/applications")
@Produces(MediaType.APPLICATION_JSON)
public JsonElement listApps() {
accessControl(Group.managers());
return view(ApplicationRegistry.availableApplications());
}
@POST
@Path("/applications")
@Consumes(MediaType.APPLICATION_JSON)
public JsonElement installApp(JsonObject obj) {
accessControl(Group.managers());
MenuContainer container = readDomainObject(obj.get("root").getAsString());
Application app = ApplicationRegistry.getAppByKey(obj.get("key").getAsString());
if (app == null) {
throw new WebApplicationException(Status.NOT_FOUND);
}
return viewMenu(doInstall(app, container));
}
@POST
@Path("/functionalities")
@Consumes(MediaType.APPLICATION_JSON)
public JsonElement installFunctionality(JsonObject obj) {
accessControl(Group.managers());
MenuContainer container = readDomainObject(obj.get("root").getAsString());
Application app = ApplicationRegistry.getAppByKey(obj.get("appKey").getAsString());
if (app == null) {
throw new WebApplicationException(Status.NOT_FOUND);
}
Optional<MenuFunctionality> functionality =
app.getFunctionalities()
.stream()
.filter(f -> f.getProvider().equals(obj.get("provider").getAsString())
&& f.getKey().equals(obj.get("key").getAsString())).findAny().map(f -> doInstall(container, f));
if (functionality.isPresent()) {
return viewMenu(functionality.get());
}
throw new WebApplicationException(Status.NOT_FOUND);
}
@Atomic(mode = TxMode.WRITE)
private MenuFunctionality doInstall(MenuContainer container, Functionality functionality) {
return new MenuFunctionality(container, functionality);
}
@Atomic(mode = TxMode.WRITE)
private MenuContainer doInstall(Application app, MenuContainer container) {
return new MenuContainer(container, app);
}
private MenuItem getMenuItem(String oid) {
return readDomainObject(oid);
}
}