/*
* Copyright (c) 1999-2002 ChurchillObjects.com All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. Neither the name of the copyright
* holder nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT, INCLUDING NEGLIGENCE OR OTHERWISE, ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*/
package churchillobjects.rss4j.generator;
import java.util.Enumeration;
import org.w3c.dom.Element;
import churchillobjects.rss4j.RssChannel;
import churchillobjects.rss4j.RssChannelImage;
import churchillobjects.rss4j.RssChannelItem;
import churchillobjects.rss4j.RssChannelTextInput;
import churchillobjects.rss4j.RssDocument;
import churchillobjects.rss4j.model.DateLanguageUtil;
/**
* A generator to create XML code conformant to the RSS 0.91 standard.
* Limits on lengths of text and numerical values is enforced.
* More information on the 0.91 standard can be found at the following
* links:
* <ul><li>http://backend.userland.com/rss091</li>
* <li>http://www.purplepages.ie/RSS/netscape/rss0.91.html</li>
* <li>http://my.netscape.com/publish/formats/rss-spec-0.91.html</li></ul>
*/
class RssGeneratorImpl091 extends RssGeneratorImpl090{
/**
* Constructor.
* @throws RssGenerationException
*/
RssGeneratorImpl091() throws RssGenerationException{
super();
}
/** Document type identifier, required */
private static final String DOCTYPE = "-//Netscape Communications//DTD RSS 0.91//EN";
/** Document type definition, required */
private static final String DTD = "http://my.netscape.com/publish/formats/rss-0.91.dtd";
/** RSS version identifier, required */
private static final String VERSION = "0.91";
/**
* Sets the maximum field lengths for elements in RSS 0.91.
*/
protected void setMaxLengths(){
super.setMaxLengths();
channelTitleMax = 100;
channelLinkMax = 500;
channelPubDate = 100;
channelBuildDate = 100;
channelManagingEditorMax = 100;
channelWebmasterMax = 100;
channelCopyrightMax = 100;
channelDocsMax = 500;
imageTitleMax = 100;
imageDescriptionMax = 100;
itemDescriptionMax = 500;
textInputTitleMax = 100;
textInputDescriptionMax = 500;
textInputNameMax = 20;
textInputLinkMax = 500;
}
protected void createRssDocument(RssDocument data){
doc = domImpl.createDocument(null, "rss", null);
rootElement = doc.getDocumentElement();
rootElement.setAttribute("version", VERSION);
}
protected void handleChannel(RssChannel channel) throws RssGenerationException{
Element channelElement = doc.createElement("channel");
rootElement.appendChild(channelElement);
handleChannelTitle(channel, channelElement);
handleChannelDescription(channel, channelElement);
handleChannelLink(channel, channelElement);
handleChannelLanguage(channel, channelElement);
handleChannelPicsRating(channel, channelElement);
handleChannelPubDate(channel, channelElement);
handleChannelBuildDate(channel, channelElement);
handleChannelManagingEditor(channel, channelElement);
handleChannelWebmaster(channel, channelElement);
handleChannelCopyright(channel, channelElement);
handleChannelDocs(channel, channelElement);
handleSkipDays(channel, channelElement);
handleSkipHours(channel, channelElement);
handleTextInput(channel, channelElement);
handleImage(channel, channelElement);
handleItems(channel, channelElement);
}
protected void handleSkipDays(RssChannel channel, Element channelElement){
Enumeration days = channel.skipDays();
if(days.hasMoreElements()){
Element skipDaysElement = doc.createElement("skipDays");
while(days.hasMoreElements()){
add(skipDaysElement, "day", (String)days.nextElement());
}
channelElement.appendChild(skipDaysElement);
}
}
protected void handleSkipHours(RssChannel channel, Element channelElement){
Enumeration hours = channel.skipHours();
if(hours.hasMoreElements()){
Element skipHoursElement = doc.createElement("skipHours");
while(hours.hasMoreElements()){
add(skipHoursElement, "hour", hours.nextElement().toString());
}
channelElement.appendChild(skipHoursElement);
}
}
protected void handleImage(RssChannel channel, Element channelElement) throws RssGenerationException{
RssChannelImage image = (RssChannelImage)channel.getChannelImage();
if(image!=null){
Element imageElement = doc.createElement("image");
handleImageTitle(image, imageElement);
handleImageUrl(image, imageElement);
handleImageLink(image, imageElement);
handleImageDescription(image, imageElement);
handleImageHeight(image, imageElement);
handleImageWidth(image, imageElement);
channelElement.appendChild(imageElement);
}
}
protected void handleItems(RssChannel channel, Element channelElement) throws RssGenerationException{
if(channel.getItemCount()>15){
throw new RssGenerationException("Channel in 0.91 RSS can only have 15 items");
}
Enumeration enumeration = channel.items();
while(enumeration.hasMoreElements()){
RssChannelItem item = (RssChannelItem)enumeration.nextElement();
Element itemElement = doc.createElement("item");
handleItemTitle(item, itemElement);
handleItemLink(item, itemElement);
handleItemDescription(item, itemElement);
channelElement.appendChild(itemElement);
}
}
protected void handleTextInput(RssChannel channel, Element channelElement) throws RssGenerationException{
RssChannelTextInput textInput = channel.getChannelTextInput();
if(textInput!=null){
Element textInputElement = doc.createElement("textInput");
handleTextInputTitle(textInput, textInputElement);
handleTextInputDescription(textInput, textInputElement);
handleTextInputName(textInput, textInputElement);
handleTextInputLink(textInput, textInputElement);
channelElement.appendChild(textInputElement);
}
}
protected void handleChannelLanguage(RssChannel channel, Element channelElement) throws RssGenerationException{
String language = channel.getChannelLanguage();
// not truncating, language must be an exact match
if(!DateLanguageUtil.isValidLanguage(language)){
throw new RssGenerationException("Channel language unknown or null: " + language);
}
add(channelElement, "language", language);
}
protected void handleChannelPicsRating(RssChannel channel, Element channelElement) throws RssGenerationException{
String picsRating = channel.getChannelPicsRating();
// not truncated, since pics rating should not exceed 500 anyway
validateValueOptional(picsRating, "Channel PICS rating", 20, 500);
add(channelElement, "rating", picsRating);
}
protected void handleChannelPubDate(RssChannel channel, Element channelElement) throws RssGenerationException{
String pubDate = channel.getChannelPubDate();
pubDate = truncate(pubDate, 100);
validateValueOptional(pubDate, "Channel pub date", 100);
add(channelElement, "pubDate", pubDate);
}
protected void handleChannelBuildDate(RssChannel channel, Element channelElement) throws RssGenerationException{
String lastBuildDate = channel.getChannelLastBuildDate();
lastBuildDate = truncate(lastBuildDate, 100);
validateValueOptional(lastBuildDate, "Channel last build date", 100);
add(channelElement, "lastBuildDate", lastBuildDate);
}
protected void handleChannelManagingEditor(RssChannel channel, Element channelElement) throws RssGenerationException{
String managingEditor = channel.getChannelManagingEditor();
managingEditor = truncate(managingEditor, 100);
validateValueOptional(managingEditor, "Channel managing editor", 100);
add(channelElement, "managingEditor", managingEditor);
}
protected void handleChannelWebmaster(RssChannel channel, Element channelElement) throws RssGenerationException{
String webmaster = channel.getChannelWebmaster();
webmaster = truncate(webmaster, 100);
validateValueOptional(webmaster, "Channel webmaster", 100);
add(channelElement, "webMaster", webmaster);
}
protected void handleChannelCopyright(RssChannel channel, Element channelElement) throws RssGenerationException{
String copyright = channel.getChannelCopyright();
copyright = truncate(copyright, 100);
validateValueOptional(copyright, "Channel copyright", 100);
add(channelElement, "copyright", copyright);
}
protected void handleChannelDocs(RssChannel channel, Element channelElement) throws RssGenerationException{
String docs = channel.getChannelDocs();
validateUri(docs);
validateValueOptional(docs, "Channel docs", 500);
add(channelElement, "docs", docs);
}
protected void handleImageDescription(RssChannelImage image, Element imageElement) throws RssGenerationException{
String description = image.getImageDescription();
validateValueOptional(description, "Image description", imageDescriptionMax);
add(imageElement, "description", description);
}
protected void handleImageHeight(RssChannelImage image, Element imageElement) throws RssGenerationException{
int height = image.getImageHeight();
if(height > 400){
throw new RssGenerationException(
"Image height optional, value must be positive integer <= 400: " + height);
}
if(height!=0){
add(imageElement, "height", ""+height);
}
}
protected void handleImageWidth(RssChannelImage image, Element imageElement) throws RssGenerationException{
int width = image.getImageWidth();
if(width > 144){
throw new RssGenerationException(
"Image width optional, value must be positive integer <= 144: " + width);
}
if(width!=0){
add(imageElement, "width", ""+width);
}
}
protected void handleItemDescription(RssChannelItem item, Element itemElement) throws RssGenerationException{
String description = item.getItemDescription();
validateValueOptional(description, "Image description", itemDescriptionMax);
add(itemElement, "description", description);
}
}