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}