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.api.core.Context;
023import org.apache.wiki.api.core.Engine;
024import org.apache.wiki.api.exceptions.NoSuchVariableException;
025import org.apache.wiki.variables.VariableManager;
026
027import jakarta.servlet.ServletContext;
028import java.util.ArrayList;
029import java.util.List;
030import org.apache.logging.log4j.LogManager;
031import org.apache.logging.log4j.Logger;
032import org.apache.wiki.providers.BasicAttachmentProvider;
033
034/**
035 * Represents an abstract feed.
036 */
037public abstract class Feed {
038    protected final List<Entry> m_entries = new ArrayList<>();
039    private static final Logger LOG = LogManager.getLogger( Feed.class );
040
041    protected String m_feedURL;
042    protected String m_channelTitle;
043    protected String m_channelDescription;
044    protected String m_channelLanguage;
045
046    protected final Context m_wikiContext;
047
048    protected String m_mode = RSSGenerator.MODE_WIKI;
049
050    /**
051     * Wiki variable storing the blog's name.
052     */
053    public static final String VAR_BLOGNAME = "blogname";
054
055    /**
056     * Figure out a site name for a feed.
057     *
058     * @param context the wiki context
059     * @return the site name
060     */
061    public static String getSiteName( final Context context ) {
062        final Engine engine = context.getEngine();
063
064        String blogname = null;
065
066        try {
067            blogname = engine.getManager( VariableManager.class ).getValue(context, VAR_BLOGNAME);
068        } catch( final NoSuchVariableException e ) {
069            LOG.debug(e.getMessage(), e);
070        }
071
072        if (blogname == null) {
073            blogname = engine.getApplicationName() + ": " + context.getPage().getName();
074        }
075
076        return blogname;
077    }
078
079    /**
080     * Create a new Feed for a particular WikiContext.
081     *
082     * @param context The WikiContext.
083     */
084    public Feed( final Context context) {
085        m_wikiContext = context;
086    }
087
088    /**
089     * Set the mode of the Feed.  It can be any of the following:
090     * <ul>
091     * <li>{@link RSSGenerator#MODE_WIKI} - to create a wiki diff list per page.</li>
092     * <li>{@link RSSGenerator#MODE_BLOG} - to assume that the Entries are blog entries.</li>
093     * <li>{@link RSSGenerator#MODE_FULL} - to create a wiki diff list for the entire blog.</li>
094     * </ul>
095     * As the Entry list itself is generated elsewhere, this mostly just affects the way
096     * that the layout and metadata for each entry is generated.
097     *
098     * @param mode As defined in RSSGenerator.
099     */
100    public void setMode( final String mode) {
101        m_mode = mode;
102    }
103
104    /**
105     * Adds a new Entry to the Feed, at the end of the list.
106     *
107     * @param e The Entry to add.
108     */
109    public void addEntry( final Entry e) {
110        m_entries.add(e);
111    }
112
113    /**
114     * Returns the XML for the feed contents in a String format.  All subclasses must implement.
115     *
116     * @return valid XML, ready to be shoved out.
117     */
118    public abstract String getString();
119
120    /**
121     * @return Returns the m_channelDescription.
122     */
123    public String getChannelDescription() {
124        return m_channelDescription;
125    }
126
127    /**
128     * @param description The m_channelDescription to set.
129     */
130    public void setChannelDescription( final String description) {
131        m_channelDescription = description;
132    }
133
134    /**
135     * @return Returns the m_channelLanguage.
136     */
137    public String getChannelLanguage() {
138        return m_channelLanguage;
139    }
140
141    /**
142     * @param language The m_channelLanguage to set.
143     */
144    public void setChannelLanguage( final String language) {
145        m_channelLanguage = language;
146    }
147
148    /**
149     * @return Returns the m_channelTitle.
150     */
151    public String getChannelTitle() {
152        return m_channelTitle;
153    }
154
155    /**
156     * @param title The m_channelTitle to set.
157     */
158    public void setChannelTitle( final String title) {
159        m_channelTitle = title;
160    }
161
162    /**
163     * @return Returns the m_feedURL.
164     */
165    public String getFeedURL() {
166        return m_feedURL;
167    }
168
169    /**
170     * @param feedurl The m_feedURL to set.
171     */
172    public void setFeedURL( final String feedurl) {
173        m_feedURL = feedurl;
174    }
175
176    /**
177     * A helper method for figuring out the MIME type for an enclosure.
178     *
179     * @param c    A ServletContext
180     * @param name The filename
181     * @return Something sane for a MIME type.
182     */
183    protected String getMimeType( final ServletContext c, final String name) {
184        String type = c.getMimeType(name);
185
186        if (type == null) {
187            type = "application/octet-stream";
188        }
189
190        return type;
191    }
192
193    /**
194     * Does the required formatting and entity replacement for XML.
195     *
196     * @param s The String to format. Null is safe.
197     * @return A formatted string.
198     */
199    public static String format( final String s ) {
200        return StringEscapeUtils.escapeXml11( s );
201    }
202}