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