/*
It is a application for event distribution to event n-consumers with m-sources.
Copyright (C) 2010 "Imran M Yousuf <imran@smartitengineering.com>"
This program 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 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.event.hub.core;
import com.smartitengineering.event.hub.api.Channel;
import com.smartitengineering.event.hub.api.impl.APIFactory;
import com.smartitengineering.event.hub.api.impl.APIFactory.ChannelBuilder;
import com.smartitengineering.event.hub.common.ChannelJsonProvider;
import com.smartitengineering.event.hub.spi.HubPersistentStorerSPI;
import com.sun.jersey.api.view.Viewable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
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.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriBuilder;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
import org.apache.abdera.model.Link;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
/**
*
* @author imyousuf
*/
@Path("/all-channels")
public class ChannelsResource extends AbstractChannelResource {
static final Method BEFORE_METHOD;
static final Method AFTER_METHOD;
static {
try {
BEFORE_METHOD = ChannelsResource.class.getMethod("getBefore", String.class);
}
catch (Exception ex) {
throw new InstantiationError();
}
try {
AFTER_METHOD = ChannelsResource.class.getMethod("getAfter", String.class);
}
catch (Exception ex) {
throw new InstantiationError();
}
}
private Integer position;
@QueryParam("count")
@DefaultValue("10")
private Integer count;
private String channelName;
private String authToken;
@GET
@Produces(MediaType.APPLICATION_ATOM_XML)
@Path("/before/{channelPosition}")
public Response getBefore(@PathParam("channelPosition") String beforeChannel) {
this.position = NumberUtils.toInt(beforeChannel);
return get(position, true);
}
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/before/{channelPosition}")
public Response getBeforeHtml(@PathParam("channelPosition") String beforeChannel) {
this.position = NumberUtils.toInt(beforeChannel);
return getInHtml(position, true);
}
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/before/{channelPosition}/frags")
public Response getBeforeHtmlFrags(@PathParam("channelPosition") String beforeChannel) {
this.position = NumberUtils.toInt(beforeChannel);
return getInHtmlFrags(position, true);
}
@GET
@Produces(MediaType.APPLICATION_ATOM_XML)
@Path("/after/{channelPosition}")
public Response getAfter(@PathParam("channelPosition") String afterChannel) {
this.position = NumberUtils.toInt(afterChannel);
return get(position, false);
}
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/after/{channelPosition}")
public Response getAfterHtml(@PathParam("channelPosition") String afterChannel) {
this.position = NumberUtils.toInt(afterChannel);
return getInHtml(position, false);
}
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/after/{channelPosition}/frags")
public Response getAfterHtmlFrags(@PathParam("channelPosition") String afterChannel) {
this.position = NumberUtils.toInt(afterChannel);
return getInHtmlFrags(position, false);
}
@GET
@Produces(MediaType.APPLICATION_ATOM_XML)
public Response get() {
return get(Integer.MAX_VALUE, true);
}
@GET
@Produces(MediaType.TEXT_HTML)
public Response getHtml() {
return getInHtml(Integer.MAX_VALUE, true);
}
@GET
@Path("/frags")
@Produces(MediaType.TEXT_HTML)
public Response getHtmlFrags() {
return getInHtmlFrags(Integer.MAX_VALUE, true);
}
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_HTML)
public Response createChannel(MultivaluedMap<String, String> formInputs) {
final ResponseBuilder builder;
String name = formInputs.getFirst(ChannelJsonProvider.NAME);
if (StringUtils.isNotBlank(name) && HubPersistentStorerSPI.getInstance().getStorer().getChannel(name) == null) {
String description = formInputs.getFirst(ChannelJsonProvider.DESCRIPTION);
this.authToken = formInputs.getFirst(ChannelJsonProvider.AUTH_TOKEN);
ChannelBuilder channelBuilder = APIFactory.getChannelBuilder(name);
if (StringUtils.isNotBlank(description)) {
channelBuilder.description(description);
}
if (StringUtils.isNotBlank(this.authToken)) {
channelBuilder.authToken(this.authToken);
}
Channel newChannel = channelBuilder.build();
boolean error = false;
String errorMessage = "";
try {
HubPersistentStorerSPI.getInstance().getStorer().create(newChannel);
}
catch (Exception ex) {
error = true;
errorMessage = ex.getMessage();
}
if (error) {
builder = Response.status(Response.Status.BAD_REQUEST);
builder.entity(errorMessage);
}
else {
Collection<Channel> channels = HubPersistentStorerSPI.getInstance().getStorer().getChannels(Integer.MAX_VALUE,
-10);
Viewable viewable = new Viewable("channels", channels, ChannelsResource.class);
builder = Response.ok(viewable);
}
}
else {
builder = Response.status(Response.Status.BAD_REQUEST);
}
return builder.build();
}
public Response getInHtml(int startIndex, boolean isBefore) {
if (count == null) {
count = 10;
}
Integer realCount = count;
if (isBefore) {
realCount = count * -1;
}
final ResponseBuilder builder = Response.ok();
Collection<Channel> channels = HubPersistentStorerSPI.getInstance().getStorer().getChannels(startIndex, realCount);
Viewable viewable = new Viewable("channels", channels, ChannelsResource.class);
builder.entity(viewable);
return builder.build();
}
public Response getInHtmlFrags(int startIndex, boolean isBefore) {
if (count == null) {
count = 10;
}
Integer realCount = count;
if (isBefore) {
realCount = count * -1;
}
final ResponseBuilder builder = Response.ok();
Collection<Channel> channels = HubPersistentStorerSPI.getInstance().getStorer().getChannels(startIndex, realCount);
Viewable viewable = new Viewable("channelsFrags", channels, ChannelsResource.class);
builder.entity(viewable);
return builder.build();
}
public Response get(int startIndex, boolean isBefore) {
if (count == null) {
count = 10;
}
int thisCount = count;
if (isBefore) {
thisCount = count * -1;
}
ResponseBuilder responseBuilder = Response.ok();
Feed atomFeed = getFeed("Events", new Date());
Link eventsLink = getAbderaFactory().newLink();
eventsLink.setHref(getRelativeURIBuilder().path(RootResource.class).build().toString());
eventsLink.setRel("root");
atomFeed.addLink(eventsLink);
Collection<Channel> channels = HubPersistentStorerSPI.getInstance().getStorer().getChannels(startIndex, thisCount);
if (channels != null && !channels.isEmpty()) {
MultivaluedMap<String, String> queryParams = getUriInfo().getQueryParameters();
List<Channel> channelList = new ArrayList<Channel>(channels);
Link nextLink = getAbderaFactory().newLink();
nextLink.setRel(Link.REL_PREVIOUS);
Channel lastChannel = channelList.get(0);
final UriBuilder nextUri = getRelativeURIBuilder().path(ChannelsResource.class).path(AFTER_METHOD);
final UriBuilder previousUri = getRelativeURIBuilder().path(ChannelsResource.class).path(BEFORE_METHOD);
for (String key : queryParams.keySet()) {
final Object[] values = queryParams.get(key).toArray();
nextUri.queryParam(key, values);
previousUri.queryParam(key, values);
}
nextLink.setHref(nextUri.build(lastChannel.getPosition()).toString());
atomFeed.addLink(nextLink);
Link previousLink = getAbderaFactory().newLink();
previousLink.setRel(Link.REL_NEXT);
Channel firstChannel = channelList.get(channels.size() - 1);
previousLink.setHref(previousUri.build(firstChannel.getPosition()).toString());
atomFeed.addLink(previousLink);
for (Channel channel : channels) {
Entry channelEntry = getAbderaFactory().newEntry();
channelEntry.setId(channel.getName());
channelEntry.setTitle(channel.getName().toString());
String content = channel.getDescription();
channelEntry.setContent(content);
channelEntry.setUpdated(channel.getCreationDateTime());
Link channelLink = getAbderaFactory().newLink();
channelLink.setHref(getRelativeURIBuilder().path(ChannelResource.class).build(channel.getName()).toString());
channelLink.setRel(Link.REL_ALTERNATE);
channelLink.setMimeType(MediaType.APPLICATION_JSON);
channelEntry.addLink(channelLink);
atomFeed.addEntry(channelEntry);
}
}
responseBuilder.entity(atomFeed);
return responseBuilder.build();
}
@Override
protected String getChannelName() {
return channelName;
}
@Override
protected String getAuthToken() {
return authToken;
}
}