/*
*
* This is a simple Content Management System (CMS)
* Copyright (C) 2010 Imran M Yousuf (imyousuf@smartitengineering.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.smartitengineering.cms.ws.resources.workspace;
import com.smartitengineering.cms.api.factory.SmartContentAPI;
import com.smartitengineering.cms.api.workspace.Workspace;
import com.smartitengineering.cms.api.factory.workspace.WorkspaceAPI;
import com.smartitengineering.cms.ws.common.providers.TextURIListProvider;
import com.smartitengineering.cms.ws.common.utils.SimpleFeedExtensions;
import com.smartitengineering.cms.ws.common.utils.Utils;
import com.smartitengineering.cms.ws.resources.content.ContentsResource;
import com.smartitengineering.cms.ws.resources.content.searcher.ContentSearcherResource;
import com.smartitengineering.cms.ws.resources.domains.Factory;
import com.smartitengineering.cms.ws.resources.type.ContentTypesResource;
import com.smartitengineering.util.rest.atom.server.AbstractResource;
import java.net.URI;
import java.util.Date;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.DELETE;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriBuilder;
import org.apache.abdera.model.Feed;
import org.apache.abdera.model.Link;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author imyousuf
*/
@Path("/w/{" + WorkspaceResource.PARAM_NAMESPACE + "}/{" + WorkspaceResource.PARAM_NAME + "}")
public class WorkspaceResource extends AbstractResource {
public static final int MAX_AGE = 1 * 60 * 60;
public static final String PARAM_NAMESPACE = "ns";
public static final String PARAM_NAME = "wsName";
public static final String PATH_FRIENDLIES = "friendlies";
public static final String PATH_REPRESENTATIONS = "representations";
public static final String PATH_CONTENT_CO_PROCESSORS = "content-co-processors";
public static final String PATH_VARIATIONS = "variations";
public static final String PATH_VALIDATORS = "validators";
public static final String PATH_SEQUENCES = "sequences";
public static final String PATH_SEARCH = "search";
public static final String PATH_REINDEX = "reindex";
public static final String REL_FRIENDLIES = "friendlies";
public static final String REL_SEQUENCES = "sequences";
public static final String REL_REPRESENTATIONS = "representations";
public static final String REL_CONTENT_CO_PROCESSORS = "contentCoProcessors";
public static final String REL_VARIATIONS = "variations";
public static final String REL_VALIDATORS = "validators";
public static final String REL_CONTENT_TYPES = "content-types";
public static final String REL_CONTENTS = "contents";
public static final String REL_SEARCH = "search";
public static final String REL_REINDEX = "re-index-all";
public static final String REL_REINDEX_CONTENTS = "re-index-contents";
public static final String REL_REINDEX_TYPES = "re-index-types";
public static final String REL_WORKSPACE_CONTENT = "workspaceContent";
private final String namespace;
private final String workspaceName;
private final Workspace workspace;
@HeaderParam(HttpHeaders.IF_MODIFIED_SINCE)
private Date ifModifiedSince;
@HeaderParam(HttpHeaders.IF_NONE_MATCH)
private EntityTag entityTag;
private final static transient Logger LOGGER = LoggerFactory.getLogger(WorkspaceResource.class);
public WorkspaceResource(@PathParam(PARAM_NAMESPACE) String namespace, @PathParam(PARAM_NAME) String workspaceName) {
this.namespace = namespace;
this.workspaceName = workspaceName;
final WorkspaceAPI workspaceApi = SmartContentAPI.getInstance().getWorkspaceApi();
this.workspace = workspaceApi.getWorkspace(workspaceApi.createWorkspaceId(namespace, workspaceName));
if (this.workspace == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getWorkspaceContent() {
if (ifModifiedSince == null || ifModifiedSince.before(workspace.getCreationDate())) {
ResponseBuilder builder = Response.ok(Factory.getWorkspace(workspace));
builder.lastModified(workspace.getCreationDate());
CacheControl control = new CacheControl();
control.setMaxAge(MAX_AGE);
builder.cacheControl(control);
builder.header(HttpHeaders.VARY, HttpHeaders.ACCEPT);
return builder.build();
}
else {
return Response.status(Response.Status.NOT_MODIFIED).build();
}
}
@DELETE
public Response deleteWorkspace() {
ResponseBuilder responseBuilder = Response.status(Response.Status.OK);
if (workspace == null) {
return responseBuilder.status(Response.Status.NOT_FOUND).build();
}
SmartContentAPI.getInstance().getWorkspaceApi().deleteWorkspace(workspace.getId());
return responseBuilder.build();
}
@Path(PATH_SEARCH)
public ContentSearcherResource searchWithinWorkspace() {
ContentSearcherResource resource = new ContentSearcherResource(getInjectables());
resource.setWorkspaceId(workspace.getId().toString().replaceAll(":", ","));
return resource;
}
@Path(PATH_REINDEX)
public ReIndexResource reindexForWorkspace() {
ReIndexResource resource = new ReIndexResource(getInjectables());
resource.setWorkspaceId(workspace.getId());
return resource;
}
@Path(PATH_REINDEX + "/" + ReIndexResource.CONTENTS)
public ReIndexResource reindexForWorkspaceContents() {
ReIndexResource resource = new ReIndexResource(getInjectables());
resource.setWorkspaceId(workspace.getId());
resource.setContentsOnly(true);
return resource;
}
@Path(PATH_REINDEX + "/" + ReIndexResource.TYPES)
public ReIndexResource reindexForWorkspaceTypes() {
ReIndexResource resource = new ReIndexResource(getInjectables());
resource.setWorkspaceId(workspace.getId());
resource.setTypesOnly(true);
return resource;
}
@GET
@Produces(MediaType.APPLICATION_ATOM_XML)
public Response getWorkspaceFeed() {
final Date creationDate = workspace.getCreationDate();
final EntityTag tag = new EntityTag(DigestUtils.md5Hex(Utils.getFormattedDate(creationDate)));
if ((ifModifiedSince == null || ifModifiedSince.before(creationDate)) && (entityTag == null ||
!entityTag.equals(tag))) {
Feed feed = getFeed(workspace.getId().toString(), workspaceName, creationDate);
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_FRIENDLIES).build(namespace, workspaceName),
REL_FRIENDLIES, TextURIListProvider.TEXT_URI_LIST));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_REPRESENTATIONS).build(namespace,
workspaceName),
REL_REPRESENTATIONS, MediaType.APPLICATION_ATOM_XML));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_CONTENT_CO_PROCESSORS).build(namespace,
workspaceName),
REL_CONTENT_CO_PROCESSORS, MediaType.APPLICATION_ATOM_XML));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_VARIATIONS).build(namespace, workspaceName),
REL_VARIATIONS, MediaType.APPLICATION_ATOM_XML));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_VALIDATORS).build(namespace, workspaceName),
REL_VALIDATORS, MediaType.APPLICATION_ATOM_XML));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_SEQUENCES).build(namespace, workspaceName),
REL_SEQUENCES, MediaType.APPLICATION_ATOM_XML));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_SEARCH).build(namespace, workspaceName),
REL_SEARCH, com.smartitengineering.util.opensearch.jaxrs.MediaType.APPLICATION_OPENSEARCHDESCRIPTION_XML));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_REINDEX).build(namespace, workspaceName),
REL_REINDEX, MediaType.TEXT_PLAIN));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_REINDEX).path(ReIndexResource.CONTENTS).build(
namespace, workspaceName), REL_REINDEX_CONTENTS, MediaType.TEXT_PLAIN));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(WorkspaceResource.class).path(PATH_REINDEX).path(ReIndexResource.TYPES).build(
namespace, workspaceName), REL_REINDEX_TYPES, MediaType.TEXT_PLAIN));
feed.addLink(getLink(
getAbsoluteURIBuilder().path(ContentTypesResource.class).build(namespace, workspaceName), REL_CONTENT_TYPES,
MediaType.APPLICATION_ATOM_XML));
feed.addLink(getLink(getAbsoluteURIBuilder().path(ContentsResource.class).build(namespace, workspaceName),
REL_CONTENTS, MediaType.APPLICATION_ATOM_XML));
feed.addLink(getLink(getUriInfo().getRequestUri(), Link.REL_ALTERNATE, MediaType.APPLICATION_JSON));
feed.addSimpleExtension(SimpleFeedExtensions.WORKSPACE_NAME_SPACE, namespace);
feed.addSimpleExtension(SimpleFeedExtensions.WORKSPACE_NAME, workspaceName);
ResponseBuilder builder = Response.ok(feed);
builder.lastModified(creationDate);
CacheControl control = new CacheControl();
control.setMaxAge(MAX_AGE);
builder.cacheControl(control);
builder.tag(tag);
builder.header(HttpHeaders.VARY, HttpHeaders.ACCEPT);
return builder.build();
}
else {
return Response.status(Response.Status.NOT_MODIFIED).build();
}
}
@Path(PATH_FRIENDLIES)
public WorkspaceFriendliesResource getFriendliesResource() {
return new WorkspaceFriendliesResource(workspace, getInjectables());
}
@Path(PATH_REPRESENTATIONS)
public WorkspaceRepresentationsResource getRepresentationsResource(@QueryParam("count") @DefaultValue("10") int count) {
return new WorkspaceRepresentationsResource(workspace, count, getInjectables());
}
@Path(PATH_CONTENT_CO_PROCESSORS)
public WorkspaceContentCoProcessorsResource getContentCoProcessorsResource(
@QueryParam("count") @DefaultValue("10") int count) {
return new WorkspaceContentCoProcessorsResource(workspace, count, getInjectables());
}
@Path(PATH_VARIATIONS)
public WorkspaceVariationsResource getVariationsResource(@QueryParam("count") @DefaultValue("10") int count) {
return new WorkspaceVariationsResource(workspace, count, getInjectables());
}
@Path(PATH_VALIDATORS)
public WorkspaceValidatorsResource getValidatorsResource(@QueryParam("count") @DefaultValue("10") int count) {
return new WorkspaceValidatorsResource(workspace, count, getInjectables());
}
@Path(PATH_SEQUENCES)
public WorkspaceSequencesResource getSequencesResource() {
return new WorkspaceSequencesResource(workspace, getInjectables());
}
@Path(PATH_REPRESENTATIONS + "/name/{name}")
public WorkspaceRepresentationResource getRepresentationsResource(@PathParam("name") String name) {
return new WorkspaceRepresentationResource(name, workspace, getInjectables());
}
@Path(PATH_CONTENT_CO_PROCESSORS + "/name/{name}")
public WorkspaceContentCoProcessorResource getContentCoProcessorResource(@PathParam("name") String name) {
return new WorkspaceContentCoProcessorResource(name, workspace, getInjectables());
}
@Path(PATH_VARIATIONS + "/name/{name}")
public WorkspaceVariationResource getVariationResource(@PathParam("name") String name) {
return new WorkspaceVariationResource(name, workspace, getInjectables());
}
@Path(PATH_VALIDATORS + "/name/{name}")
public WorkspaceValidatorResource getValidatorResource(@PathParam("name") String name) {
return new WorkspaceValidatorResource(name, workspace, getInjectables());
}
public static URI getWorkspaceURI(UriBuilder builder, String namespace, String name) {
if (builder != null) {
builder.path(WorkspaceResource.class);
return builder.build(namespace, name);
}
return null;
}
public Workspace getWorkspace() {
return workspace;
}
@Override
protected String getAuthor() {
return "Smart CMS";
}
}