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.wiki.api.Release;
022import org.apache.wiki.api.core.Attachment;
023import org.apache.wiki.api.core.Context;
024import org.apache.wiki.api.core.ContextEnum;
025import org.apache.wiki.api.core.Engine;
026import org.apache.wiki.api.core.Page;
027import org.apache.wiki.api.exceptions.ProviderException;
028import org.apache.wiki.attachment.AttachmentManager;
029import org.apache.wiki.variables.VariableManager;
030import org.jdom2.Element;
031import org.jdom2.output.Format;
032import org.jdom2.output.XMLOutputter;
033
034import javax.servlet.ServletContext;
035import java.io.IOException;
036import java.io.StringWriter;
037import java.text.SimpleDateFormat;
038import java.util.ArrayList;
039import java.util.Calendar;
040import java.util.List;
041
042/**
043 *  Represents an RSS 2.0 feed (with enclosures).  This feed provides no
044 *  fizz-bang features.
045 *
046 *  @since 2.2.27
047 */
048public class RSS20Feed extends Feed
049{
050    /**
051     *  Creates an RSS 2.0 feed for the specified Context.
052     *
053     *  @param context The WikiContext.
054     */
055    public RSS20Feed( final Context context )
056    {
057        super( context );
058    }
059
060    private List<Element> getItems()
061    {
062        final ArrayList<Element> list = new ArrayList<>();
063        final SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
064
065        final Engine engine = m_wikiContext.getEngine();
066        ServletContext servletContext = null;
067
068        if( m_wikiContext.getHttpRequest() != null )
069            servletContext = m_wikiContext.getHttpRequest().getSession().getServletContext();
070
071        for( final Entry e : m_entries ) {
072            final Page p = e.getPage();
073            final String url = e.getURL();
074            final Element item = new Element( "item" );
075            item.addContent( new Element( "link" ).setText( url ) );
076            item.addContent( new Element( "title" ).setText( e.getTitle() ) );
077            item.addContent( new Element( "description" ).setText( e.getContent() ) );
078
079            //
080            //  Attachments for enclosures
081            //
082            if( engine.getManager( AttachmentManager.class ).hasAttachments( p ) && servletContext != null ) {
083                try {
084                    final List< Attachment > c = engine.getManager( AttachmentManager.class ).listAttachments( p );
085                    for( final Attachment att : c ) {
086                        final Element attEl = new Element( "enclosure" );
087                        attEl.setAttribute( "url", engine.getURL( ContextEnum.PAGE_ATTACH.getRequestContext(), att.getName(), null ) );
088                        attEl.setAttribute( "length", Long.toString( att.getSize() ) );
089                        attEl.setAttribute( "type", getMimeType( servletContext, att.getFileName() ) );
090
091                        item.addContent( attEl );
092                    }
093                } catch( final ProviderException ex ) {
094                    // FIXME: LOG.info("Can't get attachment data",ex);
095                }
096            }
097
098            //
099            //  Modification date.
100            //
101            final Calendar cal = Calendar.getInstance();
102            cal.setTime( p.getLastModified() );
103            cal.add( Calendar.MILLISECOND, -( cal.get( Calendar.ZONE_OFFSET ) + ( cal.getTimeZone().inDaylightTime( p.getLastModified() ) ?
104                    cal.get( Calendar.DST_OFFSET ) :
105                    0 ) ) );
106
107            item.addContent( new Element( "pubDate" ).setText( fmt.format( cal.getTime() ) ) );
108
109            list.add( item );
110        }
111
112        return list;
113    }
114
115    /**
116     *  {@inheritDoc}
117     */
118    @Override
119    public String getString()
120    {
121        final Engine engine = m_wikiContext.getEngine();
122        final Element root = new Element("rss");
123        root.setAttribute("version","2.0");
124
125        final Element channel = new Element("channel");
126        root.addContent( channel );
127
128        //
129        //  Mandatory parts
130        //
131        channel.addContent( new Element("title").setText( getChannelTitle() ) );
132        channel.addContent( new Element("link").setText(engine.getBaseURL()));
133        channel.addContent( new Element("description").setText( getChannelDescription() ));
134
135        //
136        //  Optional
137        //
138        channel.addContent( new Element("language").setText(getChannelLanguage()));
139        channel.addContent( new Element("generator").setText("JSPWiki "+Release.VERSTR));
140
141        String mail = engine.getManager( VariableManager.class ).getVariable(m_wikiContext,RSSGenerator.PROP_RSS_AUTHOREMAIL);
142        if( mail != null )
143        {
144            final String editor = engine.getManager( VariableManager.class ).getVariable( m_wikiContext,RSSGenerator.PROP_RSS_AUTHOR );
145
146            if( editor != null )
147                mail = mail + " ("+editor+")";
148
149            channel.addContent( new Element("managingEditor").setText(mail) );
150        }
151
152        //
153        //  Items
154        //
155
156        channel.addContent( getItems() );
157
158        //
159        //  aaand output
160        //
161        final XMLOutputter output = new XMLOutputter();
162
163        output.setFormat( Format.getPrettyFormat() );
164
165        try {
166            final StringWriter res = new StringWriter();
167            output.output( root, res );
168
169            return res.toString();
170        } catch( final IOException e ) {
171            return null;
172        }
173    }
174
175}