/**
* Copyright © 2014 Instituto Superior Técnico
*
* This file is part of FenixEdu CMS.
*
* FenixEdu CMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FenixEdu CMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FenixEdu CMS. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.cms.api.resource;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.core.rest.BennuRestResource;
import org.fenixedu.bennu.core.security.Authenticate;
import org.fenixedu.cms.api.json.CategoryAdapter;
import org.fenixedu.cms.api.json.MenuAdapter;
import org.fenixedu.cms.api.json.PageAdapter;
import org.fenixedu.cms.api.json.PostAdapter;
import org.fenixedu.cms.api.json.SiteAdapter;
import org.fenixedu.cms.domain.*;
import org.fenixedu.cms.domain.PermissionsArray.Permission;
import org.fenixedu.cms.domain.component.Component;
import org.fenixedu.commons.i18n.LocalizedString;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import pt.ist.fenixframework.Atomic;
import pt.ist.fenixframework.Atomic.TxMode;
@Path("/cms/sites")
public class SiteResource extends BennuRestResource {
//TODO: check permissions in all methods
@GET
@Produces(MediaType.APPLICATION_JSON)
public String listAllSites() {
return view(getAdminSites(), SiteAdapter.class);
}
private Stream<Site> getAdminSites() {
return Bennu.getInstance().getSitesSet().stream().filter(s -> PermissionEvaluation.canAccess(Authenticate.getUser(), s));
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String createSite(String json) {
CmsSettings.getInstance().ensureCanManageSettings();
return view(createSiteFromJson(json));
}
private Site createSiteFromJson(String json) {
return create(json, Site.class);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}")
public String listSite(@PathParam("oid") Site site) {
return view(site, SiteAdapter.class);
}
@DELETE
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}")
public Response deleteSite(@PathParam("oid") Site site) {
site.delete();
return Response.ok().build();
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}")
public String updateSite(@PathParam("oid") Site site, String json) {
return updateSiteFromJson(site, json);
}
private String updateSiteFromJson(Site site, String json) {
return view(update(json, site, SiteAdapter.class));
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/posts")
public String listSitePosts(@PathParam("oid") Site site, @QueryParam("category") final Set<Category> categories) {
Set<Post> posts = site.getPostSet();
if (categories != null && !categories.isEmpty()) {
posts = posts.stream().filter(p -> p.getCategoriesSet().stream().anyMatch(c -> categories.contains(c)))
.collect(Collectors.toSet());
}
return view(posts, PostAdapter.class);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/posts")
public String createPost(@PathParam("oid") Site site, JsonObject json) {
return view(createPostFromJson(site, json));
}
@Atomic(mode = TxMode.WRITE)
private Post createPostFromJson(Site site, JsonObject jObj) {
PermissionEvaluation.ensureCanDoThis(site, Permission.CREATE_POST);
Post post = new Post(site);
if (jObj.has("name") && !jObj.get("name").isJsonNull() && jObj.get("name").isJsonObject()) {
post.setName(LocalizedString.fromJson(jObj.get("name")));
}
if (jObj.has("slug") && !jObj.get("slug").isJsonNull()) {
post.setSlug(jObj.get("slug").getAsString());
}
if (jObj.has("body") && !jObj.get("body").isJsonNull() && jObj.get("body").isJsonObject()) {
LocalizedString excerpt = null;
if(jObj.has("excerpt") && !jObj.get("excerpt").isJsonNull() && jObj.get("excerpt").isJsonObject()) {
excerpt = LocalizedString.fromJson(jObj.get("excerpt"));
}
post.setBodyAndExcerpt(LocalizedString.fromJson(jObj.get("body")), excerpt);
}
return post;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/pages")
public String listSitePages(@PathParam("oid") Site site) {
return view(site.getPagesSet(), PageAdapter.class);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/pages")
public String createPage(@PathParam("oid") Site site, JsonObject json) {
return view(createPageFromJson(site, json));
}
@Atomic(mode = TxMode.WRITE)
private Page createPageFromJson(Site site, JsonObject jObj) {
PermissionEvaluation.ensureCanDoThis(site, Permission.CREATE_PAGE);
if (jObj.has("name") && !jObj.get("name").isJsonNull() && jObj.get("name").isJsonObject()) {
Page page = new Page(site, LocalizedString.fromJson(jObj.get("name")));
if (jObj.has("slug") && !jObj.get("slug").isJsonNull()) {
page.setSlug(jObj.get("slug").getAsString());
}
if (jObj.has("published") && !jObj.get("published").isJsonNull()) {
page.setPublished(jObj.get("published").getAsBoolean());
}
return page;
}
return null;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/categories")
public String listSiteCategories(@PathParam("oid") Site site) {
return view(site.getCategoriesSet(), CategoryAdapter.class);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/categories")
public String createCategory(@PathParam("oid") Site site, JsonObject json) {
return view(createCategoryFromJson(site, json));
}
@Atomic(mode = TxMode.WRITE)
private Category createCategoryFromJson(Site site, JsonObject jObj) {
if (jObj.has("name") && !jObj.get("name").isJsonNull() && jObj.get("name").isJsonObject()) {
PermissionEvaluation.ensureCanDoThis(site, Permission.CREATE_CATEGORY);
Category category = new Category(site, LocalizedString.fromJson(jObj.get("name")));
if (jObj.has("slug") && !jObj.get("slug").isJsonNull()) {
category.setSlug(jObj.get("slug").getAsString());
}
return category;
}
return null;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/menus")
public String listSiteMenus(@PathParam("oid") Site site) {
return view(site.getOrderedMenusSet(), MenuAdapter.class);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/menus")
public String createMenu(@PathParam("oid") Site site, JsonObject json) {
return view(createMenuFromJson(site, json));
}
@Atomic(mode = TxMode.WRITE)
private Menu createMenuFromJson(Site site, JsonObject jObj) {
if (jObj.has("name") && !jObj.get("name").isJsonNull() && jObj.get("name").isJsonObject()) {
PermissionEvaluation.ensureCanDoThis(site, Permission.CREATE_MENU);
Menu menu = new Menu(site, LocalizedString.fromJson(jObj.get("name")));
if (jObj.has("slug") && !jObj.get("slug").isJsonNull()) {
menu.setSlug(jObj.get("slug").getAsString());
}
if (jObj.has("topMenu") && !jObj.get("topMenu").isJsonNull()) {
menu.setTopMenu(jObj.get("topMenu").getAsBoolean());
}
return menu;
}
return null;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{oid}/components")
public JsonArray listSiteAvailableComponents(@PathParam("oid") Site site) {
return Component.availableComponents(site);
}
}