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.plugin; 020 021import java.text.SimpleDateFormat; 022import java.util.Calendar; 023import java.util.Collection; 024import java.util.Comparator; 025import java.util.Date; 026import java.util.Iterator; 027import java.util.List; 028import java.util.Map; 029import java.util.SortedSet; 030import java.util.TreeSet; 031 032import org.apache.log4j.Logger; 033import org.apache.wiki.WikiContext; 034import org.apache.wiki.WikiEngine; 035import org.apache.wiki.WikiPage; 036import org.apache.wiki.api.exceptions.PluginException; 037import org.apache.wiki.api.exceptions.ProviderException; 038import org.apache.wiki.api.plugin.WikiPlugin; 039import org.apache.wiki.util.TextUtil; 040 041/** 042 * Creates a list of all weblog entries on a monthly basis. 043 * 044 * <p>Parameters : </p> 045 * <ul> 046 * <li><b>page</b> - the page name</li> 047 * </ul> 048 * 049 * @since 1.9.21 050 */ 051public class WeblogArchivePlugin implements WikiPlugin 052{ 053 private static Logger log = Logger.getLogger(WeblogArchivePlugin.class); 054 055 /** Parameter name for setting the page. Value is <tt>{@value}</tt>. */ 056 public static final String PARAM_PAGE = "page"; 057 058 private SimpleDateFormat m_monthUrlFormat; 059 060 /** 061 * {@inheritDoc} 062 */ 063 public String execute( WikiContext context, Map<String, String> params ) 064 throws PluginException 065 { 066 WikiEngine engine = context.getEngine(); 067 068 // 069 // Parameters 070 // 071 String weblogName = params.get( PARAM_PAGE ); 072 073 if( weblogName == null ) weblogName = context.getPage().getName(); 074 075 076 m_monthUrlFormat = new SimpleDateFormat("'"+ 077 context.getURL( WikiContext.VIEW, weblogName, 078 "weblog.startDate='ddMMyy'&weblog.days=%d")+"'"); 079 080 StringBuilder sb = new StringBuilder(); 081 082 sb.append( "<div class=\"weblogarchive\">\n" ); 083 084 085 // 086 // Collect months that have blog entries 087 // 088 089 try 090 { 091 Collection months = collectMonths( engine, weblogName ); 092 int year = 0; 093 094 // 095 // Output proper HTML. 096 // 097 098 sb.append( "<ul>\n" ); 099 100 if( months.size() > 0 ) 101 { 102 year = ((Calendar)months.iterator().next()).get( Calendar.YEAR ); 103 104 sb.append( "<li class=\"archiveyear\">"+year+"</li>\n" ); 105 } 106 107 for( Iterator i = months.iterator(); i.hasNext(); ) 108 { 109 Calendar cal = (Calendar) i.next(); 110 111 if( cal.get( Calendar.YEAR ) != year ) 112 { 113 year = cal.get( Calendar.YEAR ); 114 115 sb.append( "<li class=\"archiveyear\">"+year+"</li>\n" ); 116 } 117 118 sb.append( " <li>" ); 119 120 sb.append( getMonthLink( cal ) ); 121 122 sb.append( "</li>\n" ); 123 } 124 125 sb.append( "</ul>\n" ); 126 sb.append( "</div>\n" ); 127 } 128 catch( ProviderException ex ) 129 { 130 log.info( "Cannot get archive", ex ); 131 sb.append("Cannot get archive: "+ex.getMessage()); 132 } 133 134 return sb.toString(); 135 } 136 137 @SuppressWarnings("unchecked") 138 private SortedSet collectMonths( WikiEngine engine, String page ) 139 throws ProviderException 140 { 141 Comparator comp = new ArchiveComparator(); 142 TreeSet<Calendar> res = new TreeSet<Calendar>( comp ); 143 144 WeblogPlugin pl = new WeblogPlugin(); 145 146 List blogEntries = pl.findBlogEntries( engine.getPageManager(), 147 page, new Date(0L), new Date() ); 148 149 for( Iterator i = blogEntries.iterator(); i.hasNext(); ) 150 { 151 WikiPage p = (WikiPage) i.next(); 152 153 // FIXME: Not correct, should parse page creation time. 154 155 Date d = p.getLastModified(); 156 Calendar cal = Calendar.getInstance(); 157 cal.setTime( d ); 158 res.add( cal ); 159 } 160 161 return res; 162 } 163 164 private String getMonthLink( Calendar day ) 165 { 166 SimpleDateFormat monthfmt = new SimpleDateFormat( "MMMM" ); 167 String result; 168 169 if( m_monthUrlFormat == null ) 170 { 171 result = monthfmt.format( day.getTime() ); 172 } 173 else 174 { 175 Calendar cal = (Calendar)day.clone(); 176 int firstDay = cal.getActualMinimum( Calendar.DATE ); 177 int lastDay = cal.getActualMaximum( Calendar.DATE ); 178 179 cal.set( Calendar.DATE, lastDay ); 180 String url = m_monthUrlFormat.format( cal.getTime() ); 181 182 url = TextUtil.replaceString( url, "%d", Integer.toString( lastDay-firstDay+1 ) ); 183 184 result = "<a href=\""+url+"\">"+monthfmt.format(cal.getTime())+"</a>"; 185 } 186 187 return result; 188 189 } 190 191 192 /** 193 * This is a simple comparator for ordering weblog archive entries. 194 * Two dates in the same month are considered equal. 195 */ 196 private static class ArchiveComparator 197 implements Comparator 198 { 199 200 public int compare( Object a, Object b ) 201 { 202 if( a == null || b == null || 203 !(a instanceof Calendar) || !(b instanceof Calendar) ) 204 { 205 throw new ClassCastException( "Invalid calendar supplied for comparison." ); 206 } 207 208 Calendar ca = (Calendar) a; 209 Calendar cb = (Calendar) b; 210 if( ca.get( Calendar.YEAR ) == cb.get( Calendar.YEAR ) && 211 ca.get( Calendar.MONTH ) == cb.get( Calendar.MONTH ) ) 212 { 213 return 0; 214 } 215 216 return cb.getTime().before( ca.getTime() ) ? 1 : -1; 217 } 218 } 219}