com.day.cq.commons.feed.AbstractFeed Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*
* Copyright 1997-2008 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.commons.feed;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ResourceNotFoundException;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Property;
import javax.servlet.ServletException;
import java.util.Calendar;
import java.util.SimpleTimeZone;
import java.util.Iterator;
import java.util.ArrayList;
import java.io.IOException;
import com.day.cq.commons.SimpleXml;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.text.Text;
/**
* The AbstractFeed
serves as a base for classes printing
* resources as feeds.
*/
public abstract class AbstractFeed implements Feed {
/**
* default logger
*/
final Logger log = LoggerFactory.getLogger(Feed.class);
static final String[] textNodes = new String[3]; // todo: make configurable
static {
textNodes[0] = "par/text";
textNodes[1] = "par/textimage";
textNodes[2] = "blogentry";
}
SimpleXml xml;
SlingHttpServletRequest request;
SlingHttpServletResponse response;
String title;
String description;
String tags;
String language;
String author;
String publishedDate;
String nodePath;
String baseUrl;
long fileSize;
String mimeType;
/**
* Creates a new feed instance using the specified resource.
* @param res The resource
* @param req The servlet request
* @param resp The servlet response
* @throws RepositoryException if no node can be found
*/
public AbstractFeed(Resource res, SlingHttpServletRequest req,
SlingHttpServletResponse resp)
throws RepositoryException {
request = req;
response = resp;
if (res == null) {
res = request.getResource();
}
if (ResourceUtil.isNonExistingResource(res)) {
throw new ResourceNotFoundException("No data to render.");
}
Node node = res.adaptTo(Node.class);
if (node == null) {
throw new RepositoryException("No node found for resource: " + res.getPath());
}
// if available, make sure we get the properties from jcr:content,
// but the path from the parent
Resource propRes = res;
nodePath = node.getPath();
if (node.getName().equals(JcrConstants.JCR_CONTENT)) {
nodePath = node.getParent().getPath();
} else if (node.hasNode(JcrConstants.JCR_CONTENT)) {
propRes = res.getChild(JcrConstants.JCR_CONTENT);
}
ValueMap props = propRes.adaptTo(ValueMap.class);
if (node.isNodeType(JcrConstants.NT_FILE)) {
fileSize = (props.get(JcrConstants.JCR_DATA, Property.class) != null) ? props.get(JcrConstants.JCR_DATA, Property.class).getLength() : 0;
mimeType = props.get(JcrConstants.JCR_MIMETYPE, "application/octet-stream");
} else {
mimeType = "text/html";
}
// links & paths
baseUrl = getUrlPrefix();
baseUrl += Text.getRelativeParent(nodePath, 1);
// content
title = props.get(JcrConstants.JCR_TITLE, node.getName());
description = props.get(JcrConstants.JCR_DESCRIPTION, "");
language = props.get(JcrConstants.JCR_LANGUAGE, "");
author = props.get(JcrConstants.JCR_CREATED_BY, "");
publishedDate = formatDate(props.get(JcrConstants.JCR_CREATED, props.get("cq:lastModified", Calendar.getInstance())));
tags = Text.implode(props.get("cq:tags", new String[0]), ",");
}
/**
* {@inheritDoc}
*/
public String getContentType() {
return Feed.DEFAULT_CONTENT_TYPE;
}
/**
* {@inheritDoc}
*/
public String getCharacterEncoding() {
return Feed.DEFAULT_CHARACTER_ENCODING;
}
/**
* {@inheritDoc}
*/
public void printEntry(Resource res) throws IOException {
initXml();
try {
// make sure wrapper elements are omitted when including the resource
request.setAttribute("com.day.cq.wcm.api.components.ComponentContext/bypass", "true");
StringResponseWrapper wrapper = new StringResponseWrapper(response);
request.getRequestDispatcher(getFeedEntryPath(res)).include(request, wrapper);
xml.getWriter().print(wrapper.getString());
} catch (ServletException se) {
throw new IOException(se.getMessage());
}
}
/**
* {@inheritDoc}
*/
public void printChildEntries() throws IOException {
printEntries(request.getResourceResolver().listChildren(request.getResource()));
}
/**
* {@inheritDoc}
*/
public void printChildEntries(int max) throws IOException {
Iterator iter = request.getResourceResolver().listChildren(request.getResource());
ArrayList children = new ArrayList();
while (iter.hasNext()) {
Resource res = iter.next();
try {
if (res.adaptTo(Node.class).getName().equals(JcrConstants.JCR_CONTENT)) {
// skip self
continue;
}
} catch (RepositoryException re) {
throw new IOException(re.getMessage());
}
children.add(res);
}
printEntries(children.iterator(), max);
}
/**
* {@inheritDoc}
*/
public void printEntries(Iterator iter) throws IOException {
printEntries(iter, 0);
}
/**
* {@inheritDoc}
*/
public void printEntries(Iterator iter, int max) throws IOException {
int i = 0;
while (iter.hasNext()) {
printEntry(iter.next());
if (max > 0 && ++i > max) {
break;
}
}
}
/**
* {@inheritDoc}
*/
public void printFooter() throws IOException {
initXml();
xml.closeDocument();
}
/**
* Initializes the XML writer.
* @throws IOException If output fails
*/
void initXml() throws IOException {
if (xml == null) {
xml = new SimpleXml(response.getWriter());
}
}
/**
* Returns the path to the feed entry for the specified resource.
* @param res The resource
* @return The path
*/
String getFeedEntryPath(Resource res) {
return res.getPath() + Feed.SUFFIX_FEEDENTRY;
}
/**
* Formats the date according to the sepification of the feed.
* Default is UTC.
* @param calendar The calendar
* @return The formatted date
*/
String formatDate(Calendar calendar) {
// UTC
try {
calendar.setTimeZone(new SimpleTimeZone(0, "UTC"));
return String.format("%1$tFT%1$tTZ", calendar);
} catch (Exception e) {
return "";
}
}
/**
* States whether the feed is a file
* @return true
if feed is binary, false
otherwise
*/
boolean isFile() {
return fileSize > 0;
}
/**
* Returns the file size of the feed.
* @return The size
*/
String getFileSize() {
return fileSize + "";
}
/**
* Returns the mime type of the feed.
* @return The type
*/
String getMimeType() {
return mimeType;
}
/**
* Returns the title of the feed.
* @return The title
*/
String getTitle() {
return title;
}
/**
* Returns the summary of the feed.
* @return The summary
*/
String getSummary() {
return description;
}
/**
* Returns the description of the feed.
* @return The description
*/
@SuppressWarnings({"ConstantConditions"})
String getDescription() {
return description;
}
/**
* Returns the comma-separated tags (or categories) of the feed.
* @return The tags
*/
String getTags() {
return tags;
}
/**
* Returns the language of the feed.
* @return The language
*/
String getLanguage() {
return language;
}
/**
* Returns the author's name.
* @return The name
*/
String getAuthorName() {
return author;
}
/**
* Returns the author's e-mail address.
* @return The e-mail address
*/
String getAuthorEmail() {
return !"".equals(author) ? author + "@" + request.getServerName() : "";
}
/**
* Returns the formatted date the feed was published.
* @return The date
*/
String getPublishedDate() {
return publishedDate;
}
/**
* Returns the path of the content node of the feed.
* @return The path
*/
String getNodePath() {
return nodePath;
}
/**
* Returns the prefix for links including scheme, server name,
* server port (if applicable) and context path.
* @return The URL prefix
*/
String getUrlPrefix() {
StringBuffer url = new StringBuffer();
int port = request.getServerPort();
int defaultPort = "http".equals(request.getScheme()) ? 80 : "https".equals(request.getScheme()) ? 443 : -1;
url.append(request.getScheme());
url.append("://");
url.append(request.getServerName());
if (port > 0 && port != defaultPort) {
url.append(":");
url.append(port);
}
url.append(request.getContextPath());
return url.toString();
}
/**
* Returns the HTML link of the feed.
* @return The link
*/
String getHtmlLink() {
return getUrlPrefix() + getNodePath() + Feed.SUFFIX_HTML;
}
/**
* Returns the XML link of the feed.
* @return The link
*/
String getFeedLink() {
return getUrlPrefix() + getNodePath() + Feed.SUFFIX_FEED;
}
/**
* Returns the XML link of the feed entry.
* @return The link
*/
String getFeedEntryLink() {
return getUrlPrefix() + getNodePath() + Feed.SUFFIX_FEEDENTRY;
}
/**
* Returns the comments link of the feed.
* @return The link
*/
String getCommentsLink() {
return getUrlPrefix() + getNodePath() + Feed.SUFFIX_COMMENTS;
}
/**
* Returns the file link of the feed.
* @return The link
*/
String getFileLink() {
return getUrlPrefix() + getNodePath();
}
/**
* Returns the base URL of the feed.
* @return The base URL
*/
String getBaseUrl() {
return baseUrl;
}
/**
* Returns the name of the feed generator.
* @return The generator name
* todo: retrieve from system
*/
String getGeneratorName() {
return "CQ5";
}
/**
* Returns the version of the feed generator.
* @return The generator version
* todo: retrieve from system
*/
String getGeneratorVersion() {
return "5.2";
}
/**
* Returns the link to the feed generator.
* @return The generator link
* todo: retrieve from system
*/
String getGeneratorLink() {
return "http://www.day.com/communique";
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy