001/* 
002    Licensed to the Apache Software Foundation (ASF) under one
003    or more contributor license agreements.  See the NOTICE file
004    distributed with this work for additional information
005    regarding copyright ownership.  The ASF licenses this file
006    to you under the Apache License, Version 2.0 (the
007    "License"); you may not use this file except in compliance
008    with the License.  You may obtain a copy of the License at
009
010       http://www.apache.org/licenses/LICENSE-2.0
011
012    Unless required by applicable law or agreed to in writing,
013    software distributed under the License is distributed on an
014    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015    KIND, either express or implied.  See the License for the
016    specific language governing permissions and limitations
017    under the License.  
018 */
019package org.apache.wiki.rss;
020
021import org.apache.commons.text.StringEscapeUtils;
022import org.apache.wiki.WikiContext;
023import org.apache.wiki.WikiEngine;
024import org.apache.wiki.api.exceptions.NoSuchVariableException;
025
026import javax.servlet.ServletContext;
027import java.util.ArrayList;
028import java.util.List;
029
030/**
031 * Represents an abstract feed.
032 */
033public abstract class Feed {
034    protected List<Entry> m_entries = new ArrayList<Entry>();
035
036    protected String m_feedURL;
037    protected String m_channelTitle;
038    protected String m_channelDescription;
039    protected String m_channelLanguage;
040
041    protected WikiContext m_wikiContext;
042
043    protected String m_mode = RSSGenerator.MODE_WIKI;
044
045    /**
046     * Wiki variable storing the blog's name.
047     */
048    public static final String VAR_BLOGNAME = "blogname";
049
050    /**
051     * Figure out a site name for a feed.
052     *
053     * @param context the wiki context
054     * @return the site name
055     */
056    public static String getSiteName(WikiContext context) {
057        WikiEngine engine = context.getEngine();
058
059        String blogname = null;
060
061        try {
062            blogname = engine.getVariableManager().getValue(context, VAR_BLOGNAME);
063        } catch (NoSuchVariableException e) {
064        }
065
066        if (blogname == null) {
067            blogname = engine.getApplicationName() + ": " + context.getPage().getName();
068        }
069
070        return blogname;
071    }
072
073    /**
074     * Create a new Feed for a particular WikiContext.
075     *
076     * @param context The WikiContext.
077     */
078    public Feed(WikiContext context) {
079        m_wikiContext = context;
080    }
081
082    /**
083     * Set the mode of the Feed.  It can be any of the following:
084     * <ul>
085     * <li>{@link RSSGenerator#MODE_WIKI} - to create a wiki diff list per page.</li>
086     * <li>{@link RSSGenerator#MODE_BLOG} - to assume that the Entries are blog entries.</li>
087     * <li>{@link RSSGenerator#MODE_FULL} - to create a wiki diff list for the entire blog.</li>
088     * </ul>
089     * As the Entry list itself is generated elsewhere, this mostly just affects the way
090     * that the layout and metadata for each entry is generated.
091     *
092     * @param mode As defined in RSSGenerator.
093     */
094    public void setMode(String mode) {
095        m_mode = mode;
096    }
097
098    /**
099     * Adds a new Entry to the Feed, at the end of the list.
100     *
101     * @param e The Entry to add.
102     */
103    public void addEntry(Entry e) {
104        m_entries.add(e);
105    }
106
107    /**
108     * Returns the XML for the feed contents in a String format.  All subclasses must implement.
109     *
110     * @return valid XML, ready to be shoved out.
111     */
112    public abstract String getString();
113
114    /**
115     * @return Returns the m_channelDescription.
116     */
117    public String getChannelDescription() {
118        return m_channelDescription;
119    }
120
121    /**
122     * @param description The m_channelDescription to set.
123     */
124    public void setChannelDescription(String description) {
125        m_channelDescription = description;
126    }
127
128    /**
129     * @return Returns the m_channelLanguage.
130     */
131    public String getChannelLanguage() {
132        return m_channelLanguage;
133    }
134
135    /**
136     * @param language The m_channelLanguage to set.
137     */
138    public void setChannelLanguage(String language) {
139        m_channelLanguage = language;
140    }
141
142    /**
143     * @return Returns the m_channelTitle.
144     */
145    public String getChannelTitle() {
146        return m_channelTitle;
147    }
148
149    /**
150     * @param title The m_channelTitle to set.
151     */
152    public void setChannelTitle(String title) {
153        m_channelTitle = title;
154    }
155
156    /**
157     * @return Returns the m_feedURL.
158     */
159    public String getFeedURL() {
160        return m_feedURL;
161    }
162
163    /**
164     * @param feedurl The m_feedURL to set.
165     */
166    public void setFeedURL(String feedurl) {
167        m_feedURL = feedurl;
168    }
169
170    /**
171     * A helper method for figuring out the MIME type for an enclosure.
172     *
173     * @param c    A ServletContext
174     * @param name The filename
175     * @return Something sane for a MIME type.
176     */
177    protected String getMimeType(ServletContext c, String name) {
178        String type = c.getMimeType(name);
179
180        if (type == null) {
181            type = "application/octet-stream";
182        }
183
184        return type;
185    }
186
187    /**
188     * Does the required formatting and entity replacement for XML.
189     *
190     * @param s The String to format. Null is safe.
191     * @return A formatted string.
192     */
193    public static String format( String s ) {
194        return StringEscapeUtils.escapeXml11( s );
195    }
196}