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< Calendar > 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 = (months.iterator().next()).get( Calendar.YEAR ); 103 104 sb.append( "<li class=\"archiveyear\">"+year+"</li>\n" ); 105 } 106 107 for( Iterator< Calendar > i = months.iterator(); i.hasNext(); ) 108 { 109 Calendar cal = 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 } 127 catch( ProviderException ex ) 128 { 129 log.info( "Cannot get archive", ex ); 130 sb.append("Cannot get archive: "+ex.getMessage()); 131 } 132 133 sb.append( "</div>\n" ); 134 135 return sb.toString(); 136 } 137 138 private SortedSet< Calendar > collectMonths( WikiEngine engine, String page ) 139 throws ProviderException 140 { 141 Comparator< Calendar > comp = new ArchiveComparator(); 142 TreeSet<Calendar> res = new TreeSet<Calendar>( comp ); 143 144 WeblogPlugin pl = new WeblogPlugin(); 145 146 List< WikiPage > blogEntries = pl.findBlogEntries( engine, page, new Date(0L), new Date() ); 147 148 for( Iterator< WikiPage > i = blogEntries.iterator(); i.hasNext(); ) 149 { 150 WikiPage p = i.next(); 151 152 // FIXME: Not correct, should parse page creation time. 153 154 Date d = p.getLastModified(); 155 Calendar cal = Calendar.getInstance(); 156 cal.setTime( d ); 157 res.add( cal ); 158 } 159 160 return res; 161 } 162 163 private String getMonthLink( Calendar day ) 164 { 165 SimpleDateFormat monthfmt = new SimpleDateFormat( "MMMM" ); 166 String result; 167 168 if( m_monthUrlFormat == null ) 169 { 170 result = monthfmt.format( day.getTime() ); 171 } 172 else 173 { 174 Calendar cal = (Calendar)day.clone(); 175 int firstDay = cal.getActualMinimum( Calendar.DATE ); 176 int lastDay = cal.getActualMaximum( Calendar.DATE ); 177 178 cal.set( Calendar.DATE, lastDay ); 179 String url = m_monthUrlFormat.format( cal.getTime() ); 180 181 url = TextUtil.replaceString( url, "%d", Integer.toString( lastDay-firstDay+1 ) ); 182 183 result = "<a href=\""+url+"\">"+monthfmt.format(cal.getTime())+"</a>"; 184 } 185 186 return result; 187 188 } 189 190 191 /** 192 * This is a simple comparator for ordering weblog archive entries. 193 * Two dates in the same month are considered equal. 194 */ 195 private static class ArchiveComparator implements Comparator< Calendar > { 196 197 public int compare( Calendar a, Calendar b ) 198 { 199 if( a == null || b == null ) 200 { 201 throw new ClassCastException( "Invalid calendar supplied for comparison." ); 202 } 203 204 if( a.get( Calendar.YEAR ) == b.get( Calendar.YEAR ) && 205 a.get( Calendar.MONTH ) == b.get( Calendar.MONTH ) ) 206 { 207 return 0; 208 } 209 210 //sort recent dates first 211 return b.getTime().before( a.getTime() ) ? -1 : 1; 212 } 213 } 214}