/*
* File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.v8.feeder/src/com/alkacon/opencms/v8/feeder/CmsFeedContentMapping.java,v $
* Date : $Date: 2008/12/13 13:23:24 $
* Version: $Revision: 1.3 $
*
* This file is part of the Alkacon OpenCms Add-On Module Package
*
* Copyright (c) 2007 Alkacon Software GmbH (http://www.alkacon.com)
*
* The Alkacon OpenCms Add-On Module Package 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.
*
* The Alkacon OpenCms Add-On Module Package 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 the Alkacon OpenCms Add-On Module Package.
* If not, see http://www.gnu.org/licenses/.
*
* For further information about Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com.
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org.
*/
package com.alkacon.opencms.v8.feeder;
import com.alkacon.opencms.v8.formgenerator.database.CmsFormDataAccess;
import com.alkacon.opencms.v8.formgenerator.database.CmsFormDataBean;
import com.alkacon.opencms.v8.formgenerator.database.CmsFormDatabaseFilter;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsRequestContext;
import org.opencms.file.collectors.CmsDateResourceComparator;
import org.opencms.main.CmsException;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsHtmlExtractor;
import org.opencms.util.CmsMacroResolver;
import org.opencms.util.CmsStringUtil;
import org.opencms.xml.content.CmsXmlContent;
import org.opencms.xml.content.I_CmsXmlContentHandler;
import org.opencms.xml.types.CmsXmlHtmlValue;
import org.opencms.xml.types.I_CmsXmlContentValue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
/**
* Describes the mapping from an OpenCms XML content to a syndication feed entry.<p>
*
* @author Alexander Kandzior
* @author Michael Moossen
*
* @version $Revision: 1.3 $
*/
public class CmsFeedContentMapping {
/**
* Describes one individual mapping from an XML content field to a field of the syndication feed.<p>
*/
class CmsFeedFieldMapping {
/** The default value for the feed field in case no XML content match is found. */
private String m_defaultValue;
/** The field in the feed to map the XML content to. */
private String m_feedField;
/** The maximum length the field is allowed to have. */
private int m_maxLenght;
/** The fields in the XML content to map. */
private List m_xmlFields;
/**
* Creates a new feed field mapping to a list of XML fields with default value and max length.<p>
*
* @param xmlFields the List of field in the XML content to map (String with xpath)
* @param feedField the field in the feed to map the XML content to
* @param maxLength the maximum length the field is allowed to have
* @param defaultValue the default value for the feed field in case no XML content match is found
*/
public CmsFeedFieldMapping(List xmlFields, String feedField, int maxLength, String defaultValue) {
m_xmlFields = xmlFields;
m_feedField = feedField;
m_defaultValue = defaultValue;
m_maxLenght = maxLength;
}
/**
* Creates a new feed field mapping without default value.<p>
*
* @param xmlField the field in the XML content to map
* @param feedField the field in the feed to map the XML content to
*/
public CmsFeedFieldMapping(String xmlField, String feedField) {
this(xmlField, feedField, null);
}
/**
* Creates a new feed field mapping with default value and max length.<p>
*
* @param xmlField the field in the XML content to map
* @param feedField the field in the feed to map the XML content to
* @param maxLength the maximum length the field is allowed to have
* @param defaultValue the default value for the feed field in case no XML content match is found
*/
public CmsFeedFieldMapping(String xmlField, String feedField, int maxLength, String defaultValue) {
this(new ArrayList(Collections.singletonList(xmlField)), feedField, maxLength, defaultValue);
}
/**
* Creates a new feed field mapping with default value.<p>
*
* @param xmlField the field in the XML content to map
* @param feedField the field in the feed to map the XML content to
* @param defaultValue the default value for the feed field in case no XML content match is found
*/
public CmsFeedFieldMapping(String xmlField, String feedField, String defaultValue) {
this(xmlField, feedField, 0, defaultValue);
}
/**
* Adds another fields in the XML content to map.<p>
*
* @param xmlField the additional field in the XML content to map
*/
public void addXmlField(String xmlField) {
if (!m_xmlFields.contains(xmlField)) {
m_xmlFields.add(xmlField);
}
}
/**
* This is a special implementation that also returns true if the object compared to
* is a String equal to {@link #getFeedField()}.<p>
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
String feedField = null;
if (obj instanceof CmsFeedFieldMapping) {
feedField = ((CmsFeedFieldMapping)obj).m_feedField;
}
if (obj instanceof String) {
feedField = (String)obj;
}
return m_feedField.equals(feedField);
}
/**
* Returns the default value for the feed field in case no XML content match is found.<p>
*
* @return the default value for the feed field in case no XML content match is found
*/
public String getDefaultValue() {
return m_defaultValue;
}
/**
* Returns the field in the feed to map the XML content to.<p>
*
* @return the field in the feed to map the XML content to
*/
public String getFeedField() {
return m_feedField;
}
/**
* Returns the maximum length the field is allowed to have.<p>
*
* A value of <code>0</code> or less indicates that the field length is unlimited.<p>
*
* @return the maximum length the field is allowed to have
*/
public int getMaxLenght() {
return m_maxLenght;
}
/**
* Returns the fields in the XML content to map.<p>
*
* @return the fields in the XML content to map
*/
public List getXmlFields() {
return m_xmlFields;
}
/**
* Returns <code>true</code> in case a default value for the feed field is available.<p>
*
* @return <code>true</code> in case a default value for the feed field is available
*/
public boolean hasDefaultValue() {
return m_defaultValue != null;
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return m_feedField.hashCode();
}
/**
* Returns <code>true</code> in case the maximum length of the field has been set.<p>
*
* @return <code>true</code> in case the maximum length of the field has been set
*/
public boolean hasMaxLenghtLimit() {
return m_maxLenght > 0;
}
}
/**
* Macro resolver for generating rss entry fields.<p>
*
* It provides access to xml content fields, resource properties, data form fields and more.<p>
*/
class CmsFeedMacroResolver extends CmsMacroResolver {
/** Macro prefix name constant. */
public static final String MACRO_CONVERT_DATE = "convertToDate.";
/** Macro prefix name constant. */
public static final String MACRO_DATA = "data.";
/** Macro suffix name constant. */
public static final String MACRO_DATE = "DATE";
/** Macro name constant. */
public static final String MACRO_DESC_FORMAT = "desc.format";
/** Macro suffix name constant. */
public static final String MACRO_ID = "ID";
/** Macro prefix name constant. */
public static final String MACRO_LINK = "link.";
/** Macro null result constant. */
public static final String MACRO_NULL = "_NULL_";
/** Macro suffix name constant. */
public static final String MACRO_URI = "URI";
/** Macro prefix name constant. */
public static final String MACRO_XML = "xml.";
/** The cms context. */
private CmsObject m_cms;
/** The xml content to make available with macros. */
private CmsXmlContent m_content;
/** The optional data form data to make available with macros. */
private CmsFormDataBean m_dataBean;
/** The type (plain/html) of the last accessed xml content field. */
private String m_descType = null;
/** The locale to read the xml content fields from. */
private Locale m_locale;
/**
* Default constructor.<p>
*
* @param cms the cms context
* @param content the xml content to make available with macros
* @param locale the locale to read the xml content fields from
* @param dataBean the optional data form data to make available with macros
*/
public CmsFeedMacroResolver(CmsObject cms, CmsXmlContent content, Locale locale, CmsFormDataBean dataBean) {
m_content = content;
m_locale = locale;
m_cms = cms;
m_dataBean = dataBean;
setCmsObject(cms);
setKeepEmptyMacros(false);
}
/**
* @see org.opencms.util.CmsMacroResolver#getMacroValue(java.lang.String)
*/
public String getMacroValue(String macro) {
String ret = null;
if (macro.equals(CmsFeedMacroResolver.MACRO_DESC_FORMAT)) {
return m_descType;
} else if (macro.startsWith(CmsFeedMacroResolver.MACRO_CONVERT_DATE)) {
String dateMacro = macro.substring(CmsFeedMacroResolver.MACRO_CONVERT_DATE.length());
try {
// try to parse the date as long
ret = "" + Long.valueOf(dateMacro).longValue();
} catch (NumberFormatException e) {
ret = "-1";
// no luck parsing, so we have no date - try using other options...
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(dateMacro)) {
List items = CmsStringUtil.splitAsList(dateMacro, '|', true);
ret = "" + CmsDateResourceComparator.calculateDate(m_cms, m_content.getFile(), items, -1);
}
}
} else if (macro.startsWith(CmsFeedMacroResolver.MACRO_LINK)) {
String linkMacro = macro.substring(CmsFeedMacroResolver.MACRO_LINK.length());
ret = OpenCms.getLinkManager().getServerLink(m_cms, linkMacro);
} else if (macro.startsWith(CmsFeedMacroResolver.MACRO_XML)) {
String xmlMacro = macro.substring(CmsFeedMacroResolver.MACRO_XML.length());
if (xmlMacro.startsWith("_") && xmlMacro.endsWith("_") && (xmlMacro.length() > 2)) {
xmlMacro = xmlMacro.substring(1, xmlMacro.length() - 1);
if (xmlMacro.equals(CmsFeedMacroResolver.MACRO_URI)) {
ret = m_cms.getSitePath(m_content.getFile());
}
} else {
I_CmsXmlContentValue xmlValue = m_content.getValue(xmlMacro, m_locale);
if (xmlValue == null) {
return CmsFeedMacroResolver.MACRO_NULL;
} else {
// save the last for the desc.format macro
if (xmlValue instanceof CmsXmlHtmlValue) {
// the content is HTML
m_descType = CONTENT_TYPE_HTML;
} else {
// assume default "text/plain"
m_descType = CONTENT_TYPE_TEXT;
}
return xmlValue.getStringValue(m_cms);
}
}
} else if (macro.startsWith(I_CmsXmlContentHandler.MAPTO_PROPERTY)) {
String propertyMacro = macro.substring(I_CmsXmlContentHandler.MAPTO_PROPERTY.length());
try {
ret = m_cms.readPropertyObject(m_content.getFile(), propertyMacro, true).getValue();
if (ret == null) {
ret = "";
}
} catch (CmsException ex) {
// if property could not be read, populate the value with text from the default value field
ret = CmsFeedMacroResolver.MACRO_NULL;
}
} else if (macro.startsWith(I_CmsXmlContentHandler.MAPTO_ATTRIBUTE)) {
macro.substring(I_CmsXmlContentHandler.MAPTO_ATTRIBUTE.length());
} else if (macro.startsWith(CmsFeedMacroResolver.MACRO_DATA)) {
String dataMacro = macro.substring(CmsFeedMacroResolver.MACRO_DATA.length());
if (dataMacro.startsWith("_") && dataMacro.endsWith("_") && (dataMacro.length() > 2)) {
dataMacro = dataMacro.substring(1, dataMacro.length() - 1);
if (dataMacro.equals(CmsFeedMacroResolver.MACRO_ID)) {
return "" + m_dataBean.getEntryId();
} else if (dataMacro.equals(CmsFeedMacroResolver.MACRO_DATE)) {
return "" + m_dataBean.getDateCreated();
}
} else {
String value = m_dataBean.getFieldValue(dataMacro);
if (value != null) {
return value;
}
}
} else {
ret = super.getMacroValue(macro);
}
return ret;
}
}
/** Content type "text/html". */
public static final String CONTENT_TYPE_HTML = "text/html";
/** Content type "text/plain". */
public static final String CONTENT_TYPE_TEXT = "text/plain";
/** Constant to map to the feed entry author. */
public static final String FEED_AUTHOR = "Author";
/** Constant to map to the feed entry published date. */
public static final String FEED_DATE_PUBLISHED = "DatePublished";
/** Constant to map to the feed entry update date. */
public static final String FEED_DATE_UPDATED = "DateUpdated";
/** Constant to map to the feed entry description (also called value). */
public static final String FEED_DESCRIPTION = "Description";
/** Constant to map to the feed link. */
public static final String FEED_LINK = "Link";
/** Constant to map to the feed entry title. */
public static final String FEED_TITLE = "Title";
/** Constant array with all possible feed mappings. */
public static final String[] MAPPINGS = {
FEED_TITLE,
FEED_AUTHOR,
FEED_DESCRIPTION,
FEED_DATE_PUBLISHED,
FEED_DATE_UPDATED,
FEED_LINK};
/** Constant list with all possible feed mappings. */
public static final List MAPPINGS_LIST = Collections.unmodifiableList(Arrays.asList(MAPPINGS));
/** The data type id. */
private String m_dataType;
/** The description format. */
private String m_descFormat;
/** The map of mappings from the XML content to the feed. */
private Map m_feedMappings;
/** The max number of data entries per file. */
private int m_maxEntries;
/**
* Creates a new feed content mapping.<p>
*/
public CmsFeedContentMapping() {
m_feedMappings = new HashMap();
}
/**
* Constructor with additional parameters for data driven entries.<p>
*
* @param descFormat the description format
* @param dataType the data type id
* @param maxEntries the max number of data entries per file
*/
public CmsFeedContentMapping(String descFormat, String dataType, int maxEntries) {
this();
m_descFormat = descFormat;
m_dataType = dataType;
m_maxEntries = maxEntries;
}
/**
* Adds a new feed field mapping with default value and max length setting.<p>
*
* @param xmlFields the fields in the XML content to map
* @param feedField the field in the feed to map the XML content to
* @param maxLength the maximum length the field is allowed to have
* @param defaultValue the default value for the feed field in case no XML content match is found
*/
public void addFeedFieldMapping(List xmlFields, String feedField, int maxLength, String defaultValue) {
if (MAPPINGS_LIST.contains(feedField)) {
CmsFeedFieldMapping mapping = new CmsFeedFieldMapping(xmlFields, feedField, maxLength, defaultValue);
m_feedMappings.put(feedField, mapping);
}
}
/**
* Adds a new feed field mapping with default value and max length setting.<p>
*
* @param xmlFields the fields in the XML content to map
* @param feedField the field in the feed to map the XML content to
* @param maxLength the maximum length the field is allowed to have (will be converted to an int)
* @param defaultValue the default value for the feed field in case no XML content match is found
*/
public void addFeedFieldMapping(List xmlFields, String feedField, String maxLength, String defaultValue) {
// store mappings as xpath to allow better control about what is mapped
if (CmsStringUtil.isEmptyOrWhitespaceOnly(defaultValue)) {
// we don't allow only whitespace defaults
defaultValue = null;
}
int maxLengthInt = 0;
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(maxLength)) {
try {
maxLengthInt = Integer.parseInt(maxLength);
} catch (NumberFormatException e) {
// should not happen as the XSD already checks this
}
}
addFeedFieldMapping(xmlFields, feedField, maxLengthInt, defaultValue);
}
/**
* Returns a feed entry created from the given macro resolver using the configured rules of this content mapping.<p>
*
* @param cms the current users OpenCms context
* @param macroResolver the macro resolver to use to create the rss entry
*
* @return a feed entry created from the given macro resolver using the configured rules of this content mapping
*/
public SyndEntry getEntry(CmsObject cms, CmsMacroResolver macroResolver) {
// get all configured mappings
Set mappings = m_feedMappings.entrySet();
// create the empty syndication entry
SyndEntry result = new SyndEntryImpl();
boolean hasTitle = false;
boolean hasDescription = false;
// indicate we always want to use full links in the generated HTML output
cms.getRequestContext().setAttribute(CmsRequestContext.ATTRIBUTE_FULLLINKS, Boolean.TRUE);
Iterator i = mappings.iterator();
String link = null;
Date publishedDate = null;
while (i.hasNext()) {
Map.Entry e = (Map.Entry)i.next();
String feedField = (String)e.getKey();
CmsFeedFieldMapping mapping = (CmsFeedFieldMapping)e.getValue();
String macroValue = null;
List xmlFields = mapping.getXmlFields();
for (int j = 0, size = xmlFields.size(); j < size; j++) {
String xmlField = (String)xmlFields.get(j);
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(xmlField)) {
macroValue = macroResolver.resolveMacros(xmlField);
if (macroValue.equals(xmlField)) {
macroValue = macroResolver.getMacroValue(CmsFeedMacroResolver.MACRO_XML + xmlField);
}
if ((macroValue != null) && !macroValue.equals(CmsFeedMacroResolver.MACRO_NULL)) {
// found a matching XML content node
break;
}
}
}
String value = null;
String type = m_descFormat;
if (type == null) {
type = macroResolver.getMacroValue(CmsFeedMacroResolver.MACRO_DESC_FORMAT);
} else if (type.equals("html")) {
type = CONTENT_TYPE_HTML;
} else {
type = CONTENT_TYPE_TEXT;
}
if ((macroValue != null) && !macroValue.equals(CmsFeedMacroResolver.MACRO_NULL)) {
// value was found in the content
value = macroValue;
} else if (mapping.hasDefaultValue()
&& mapping.getDefaultValue().startsWith(I_CmsXmlContentHandler.MAPTO_PROPERTY)) {
// value not found in content and default value defines a property.
value = macroResolver.getMacroValue(mapping.getDefaultValue());
if (value.equals(CmsFeedMacroResolver.MACRO_NULL)) {
// if property could not be read, populate the value with text from the default value field
value = mapping.getDefaultValue();
}
} else if (mapping.hasDefaultValue()) {
// value not found in content, use default value
value = macroResolver.resolveMacros(mapping.getDefaultValue());
}
if (value != null) {
if (mapping.hasMaxLenghtLimit()) {
// apply length restriction if required
value = applyLengthRestriction(cms, value, mapping.getMaxLenght());
type = CONTENT_TYPE_TEXT;
}
// a value to map was found
int pos = MAPPINGS_LIST.indexOf(feedField);
switch (pos) {
case 0: // Title
result.setTitle(value);
hasTitle = true;
break;
case 1: // Author
result.setAuthor(value);
break;
case 2: // Description
SyndContent description = new SyndContentImpl();
description.setValue(value);
description.setType(type);
result.setDescription(description);
hasDescription = true;
break;
case 3: // DatePublished
publishedDate = convertToDate(value, macroResolver);
if (publishedDate != null) {
result.setPublishedDate(publishedDate);
}
break;
case 4: // DateUpdated
Date updatedDate = convertToDate(value, macroResolver);
if (updatedDate != null) {
result.setUpdatedDate(updatedDate);
}
break;
case 5: // Link
// use link as provided in content
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(value)) {
link = OpenCms.getLinkManager().getServerLink(cms, value);
}
break;
default: // unknown, this cannot happen as all mappings are checked when created
}
}
}
// remove the link processing attribute
cms.getRequestContext().removeAttribute(CmsRequestContext.ATTRIBUTE_FULLLINKS);
if (hasTitle && hasDescription) {
// we need at least an entry and an description
if (publishedDate == null) {
// no publish date given, so we use the date the content was created
result.setPublishedDate(convertToDate("dateCreated", macroResolver));
}
if (link == null) {
// calculate the link with full server path
link = OpenCms.getLinkManager().getServerLink(
cms,
macroResolver.getMacroValue(CmsFeedMacroResolver.MACRO_XML
+ "_"
+ CmsFeedMacroResolver.MACRO_URI
+ "_"));
}
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(link)) {
result.setLink(link);
}
} else {
// required mappings are not available
result = null;
}
return result;
}
/**
* Returns the path of the first XML element that is mapped to the feed Author.<p>
*
* If no XML element has been mapped to the feed Author, <code>null</code> is returned.<p>
*
* @return the path of the first XML element that is mapped to the feed Author
*/
public String getMappingForAuthor() {
CmsFeedFieldMapping mapping = (CmsFeedFieldMapping)m_feedMappings.get(FEED_AUTHOR);
return (mapping != null) ? (String)mapping.getXmlFields().get(0) : null;
}
/**
* Returns the path of the first XML element that is mapped to the feed publish Date.<p>
*
* If no XML element has been mapped to the feed publish Date, <code>null</code> is returned.<p>
*
* @return the path of the first XML element that is mapped to the feed publish Date
*/
public String getMappingForDatePublished() {
CmsFeedFieldMapping mapping = (CmsFeedFieldMapping)m_feedMappings.get(FEED_DATE_PUBLISHED);
return (mapping != null) ? (String)mapping.getXmlFields().get(0) : null;
}
/**
* Returns the path of the first XML element that is mapped to the feed update Date.<p>
*
* If no XML element has been mapped to the feed update Date, <code>null</code> is returned.<p>
*
* @return the path of the first XML element that is mapped to the feed update Date
*/
public String getMappingForDateUpdated() {
CmsFeedFieldMapping mapping = (CmsFeedFieldMapping)m_feedMappings.get(FEED_DATE_UPDATED);
return (mapping != null) ? (String)mapping.getXmlFields().get(0) : null;
}
/**
* Returns the path of the first XML element that is mapped to the feed Description.<p>
*
* If no XML element has been mapped to the feed Description, <code>null</code> is returned.<p>
*
* @return the path of the first XML element that is mapped to the feed Description
*/
public String getMappingForDescription() {
CmsFeedFieldMapping mapping = (CmsFeedFieldMapping)m_feedMappings.get(FEED_DESCRIPTION);
return (mapping != null) ? (String)mapping.getXmlFields().get(0) : null;
}
/**
* Returns the path of the first XML element that is mapped to the feed Title.<p>
*
* If no XML element has been mapped to the feed Title, <code>null</code> is returned.<p>
*
* @return the path of the first XML element that is mapped to the feed Title
*/
public String getMappingForTitle() {
CmsFeedFieldMapping mapping = (CmsFeedFieldMapping)m_feedMappings.get(FEED_TITLE);
return (mapping != null) ? (String)mapping.getXmlFields().get(0) : null;
}
/**
* Returns all rss entries from the given xml content in the given locale.<p>
*
* @param cms the cms context
* @param content the xml content to generate the rss entries for
* @param locale the locale
*
* @return a list of {@link SyndEntry} objects
*/
public List getRssEntries(CmsObject cms, CmsXmlContent content, Locale locale) {
List entries = new ArrayList();
if ((content == null) || (locale == null) || !content.hasLocale(locale)) {
// no entry can be created if input is silly
return entries;
}
// indicate we always want to use full links in the generated HTML output
cms.getRequestContext().setAttribute(CmsRequestContext.ATTRIBUTE_FULLLINKS, Boolean.TRUE);
try {
if (m_dataType == null) {
CmsMacroResolver rssMacroResolver = new CmsFeedMacroResolver(cms, content, locale, null);
SyndEntry entry = getEntry(cms, rssMacroResolver);
if (entry != null) {
entries.add(entry);
}
} else {
CmsFormDatabaseFilter filter = CmsFormDatabaseFilter.DEFAULT.filterResourceId(
content.getFile().getStructureId()).filterFormId(m_dataType).filterOrderDesc().filterIndex(
0,
m_maxEntries);
List dataBeans = CmsFormDataAccess.getInstance().readForms(filter);
Iterator it = dataBeans.iterator();
while (it.hasNext()) {
CmsFormDataBean dataBean = (CmsFormDataBean)it.next();
CmsMacroResolver rssMacroResolver = new CmsFeedMacroResolver(cms, content, locale, dataBean);
SyndEntry entry = getEntry(cms, rssMacroResolver);
if (entry != null) {
entries.add(entry);
}
}
}
} catch (Exception e) {
// something went really wrong
e.printStackTrace();
} finally {
// remove the link processing attribute
cms.getRequestContext().removeAttribute(CmsRequestContext.ATTRIBUTE_FULLLINKS);
}
return entries;
}
/**
* Applies the max length limitation of the current field to the given value.<p>
*
* @param cms the current users OpenCms context
* @param value the String value generated form the XML content value
* @param maxLength the max length setting of the current field
*
* @return the input with the max length limitation of the current field applied
*/
protected String applyLengthRestriction(CmsObject cms, String value, int maxLength) {
if (value.length() <= maxLength) {
return value;
}
String result;
// value is too long, apply limitation
try {
// try to convert html to plain text
result = CmsHtmlExtractor.extractText(value, cms.getRequestContext().getEncoding());
} catch (Exception e) {
result = value;
}
if (result.length() > maxLength) {
result = CmsStringUtil.trimToSize(result, maxLength);
}
return result;
}
/**
* Converts a value to a Date.<p>
*
* In case the value itself can not be converted to a date,
* the given value is used to access the given files attributes or properties
* using {@link CmsDateResourceComparator#calculateDate(CmsObject, org.opencms.file.CmsResource, List, long)}.<p>
*
* @param stringValue the value
* @param macroResolver the macro resolver
*
* @return the converted Date, or <code>null</code> if no convertible data was found
*/
protected Date convertToDate(String stringValue, CmsMacroResolver macroResolver) {
String macroValue = macroResolver.getMacroValue(CmsFeedMacroResolver.MACRO_CONVERT_DATE + stringValue);
Date result = null;
try {
// try to parse the date as long
long date = Long.valueOf(macroValue).longValue();
if (date != -1) {
result = new Date(date);
}
} catch (NumberFormatException e) {
// no luck parsing, skip value
}
return result;
}
}