/*
* Weblounge: Web Content Management System
* Copyright (c) 2003 - 2011 The Weblounge Team
* http://entwinemedia.com/weblounge
*
* 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 2
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package ch.entwine.weblounge.cache.impl.endpoint;
import ch.entwine.weblounge.cache.impl.CacheConfiguration;
import ch.entwine.weblounge.cache.impl.CacheConfigurationFactory;
import ch.entwine.weblounge.cache.impl.CacheServiceImpl;
import ch.entwine.weblounge.common.site.Site;
import ch.entwine.weblounge.common.url.UrlUtils;
import ch.entwine.weblounge.kernel.site.SiteManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URL;
import java.util.Dictionary;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
/**
* This class implements the <code>REST</code> endpoint for page data.
*/
@Path("/")
@Produces(MediaType.APPLICATION_XML)
public class CacheEndpoint {
/** The logging facility */
private static final Logger logger = LoggerFactory.getLogger(CacheEndpoint.class);
/** The endpoint documentation */
private String docs = null;
/** The cache configuration factory */
private CacheConfigurationFactory configFactory = null;
/** The sites that are online */
protected transient SiteManager sites = null;
/**
* Returns the statistics for the site cache.
*
* @param request
* the request
* @return the statistics
*/
@GET
@Path("/")
public Response getStatistics(@Context HttpServletRequest request) {
// Get the site's cache
Site site = getSite(request);
CacheConfiguration cache = getCache(site);
StringBuilder stats = new StringBuilder();
stats.append("<cache id=\"").append(cache.getIdentifier()).append("\">");
// Status
stats.append("<enabled>").append(cache.isEnabled()).append("</enabled>");
stats.append("</cache>");
Response response = Response.ok(stats.toString()).build();
return response;
}
/**
* Enables the cache for the site determined by the request.
*
* @param request
* the request
*/
@PUT
@Path("/")
public Response startCache(@Context HttpServletRequest request) {
// Get the site's cache
Site site = getSite(request);
CacheConfiguration cache = getCache(site);
// Is the cache already enabled?
if (cache.isEnabled()) {
ResponseBuilder response = Response.notModified();
return response.build();
}
// Enable the cache
try {
configFactory.enable(cache);
} catch (Throwable t) {
throw new WebApplicationException();
}
// Send the response
ResponseBuilder response = Response.ok();
return response.build();
}
/**
* Disables the cache for the site determined by the request.
*
* @param request
* the request
*/
@DELETE
@Path("/")
public Response stopCache(@Context HttpServletRequest request) {
// Extract the site
Site site = getSite(request);
if (site == null)
throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);
// Get the site's cache
CacheConfiguration cache = getCache(site);
if (cache == null)
throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);
// Is the cache already disabled?
if (!cache.isEnabled()) {
ResponseBuilder response = Response.notModified();
return response.build();
}
// Disable the cache
try {
configFactory.disable(cache);
} catch (Throwable t) {
throw new WebApplicationException();
}
// Send the response
ResponseBuilder response = Response.ok();
return response.build();
}
/**
* Disables the cache for the site determined by the request.
*
* @param request
* the request
*/
@DELETE
@Path("/content")
public Response clear(@Context HttpServletRequest request) {
// Extract the site
Site site = getSite(request);
if (site == null)
throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);
// Get the site's cache
CacheConfiguration cache = getCache(site);
if (cache == null)
throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);
// Clear the cache
try {
Dictionary<Object, Object> properties = cache.getProperties();
properties.put(CacheServiceImpl.OPT_CLEAR, "true");
// Tell the configuration admin service to update the service
cache.getConfiguration().update(properties);
properties.remove(CacheServiceImpl.OPT_CLEAR);
cache.getConfiguration().update(properties);
} catch (Throwable t) {
logger.error("Error updating cache '{}': {}", site.getIdentifier(), t.getMessage());
throw new WebApplicationException();
}
// Send the response
ResponseBuilder response = Response.ok();
return response.build();
}
/**
* Returns the endpoint documentation.
*
* @return the endpoint documentation
*/
@GET
@Path("/docs")
@Produces(MediaType.TEXT_HTML)
public String getDocumentation(@Context HttpServletRequest request) {
if (docs == null) {
String docsPath = request.getRequestURI();
String docsPathExtension = request.getPathInfo();
String servicePath = request.getRequestURI().substring(0, docsPath.length() - docsPathExtension.length());
docs = CacheEndpointDocs.createDocumentation(servicePath);
}
return docs;
}
/**
* Extracts the site from the request and returns it. If the site is not found
* or it's not running, a corresponding <code>WebApplicationException</code>
* is thrown.
*
* @param request
* the http request
* @return the site
* @throws WebApplicationException
* if the site is not found or is not running
*/
protected Site getSite(HttpServletRequest request)
throws WebApplicationException {
URL url = UrlUtils.toURL(request, false, false);
Site site = sites.findSiteByURL(url);
if (site == null) {
throw new WebApplicationException(Status.NOT_FOUND);
} else if (!site.isOnline()) {
throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);
}
return site;
}
/**
* Returns the configuration of the cache of the given site or
* <code>null</code> if no such cache was registered.
*
* @param id
* the cache identifier
* @return the cache configuration
* @throws WebApplicationException
* if the cache is not available
*/
private CacheConfiguration getCache(Site site) throws WebApplicationException {
CacheConfiguration config = configFactory.getConfiguration(site.getIdentifier());
if (config == null)
throw new WebApplicationException(Status.NOT_FOUND);
return config;
}
/**
* Callback for OSGi to set the site manager.
*
* @param siteManager
* the site manager
*/
void setSiteManager(SiteManager siteManager) {
this.sites = siteManager;
}
/**
* Callback from the OSGi declarative services environment that will pass in a
* reference to the cache configuration factory.
*
* @param factory
* the configuration factory
*/
synchronized void setCacheConfigurationFactory(
CacheConfigurationFactory factory) {
configFactory = factory;
}
/**
* {@inheritDoc}
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Cache rest endpoint";
}
}