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 org.apache.wiki.api.core.Context; 022import org.apache.wiki.api.core.ContextEnum; 023import org.apache.wiki.api.core.Engine; 024import org.apache.wiki.api.core.Page; 025import org.apache.wiki.api.exceptions.PluginException; 026import org.apache.wiki.api.plugin.Plugin; 027import org.apache.wiki.util.TextUtil; 028 029import java.text.SimpleDateFormat; 030import java.util.Calendar; 031import java.util.Collection; 032import java.util.Comparator; 033import java.util.Date; 034import java.util.List; 035import java.util.Map; 036import java.util.SortedSet; 037import java.util.TreeSet; 038 039/** 040 * Creates a list of all weblog entries on a monthly basis. 041 * 042 * <p>Parameters : </p> 043 * <ul> 044 * <li><b>page</b> - the page name</li> 045 * </ul> 046 * 047 * @since 1.9.21 048 */ 049public class WeblogArchivePlugin implements Plugin { 050 051 /** Parameter name for setting the page. Value is <tt>{@value}</tt>. */ 052 public static final String PARAM_PAGE = "page"; 053 054 private SimpleDateFormat m_monthUrlFormat; 055 056 /** 057 * {@inheritDoc} 058 */ 059 @Override 060 public String execute( final Context context, final Map< String, String > params ) throws PluginException { 061 final Engine engine = context.getEngine(); 062 063 // Parameters 064 String weblogName = params.get( PARAM_PAGE ); 065 066 if( weblogName == null ) { 067 weblogName = context.getPage().getName(); 068 } 069 070 final String pttrn = "'" + context.getURL( ContextEnum.PAGE_VIEW.getRequestContext(), weblogName,"weblog.startDate='ddMMyy'&weblog.days=%d" ) + "'"; 071 m_monthUrlFormat = new SimpleDateFormat( pttrn ); 072 073 final StringBuilder sb = new StringBuilder(); 074 sb.append( "<div class=\"weblogarchive\">\n" ); 075 076 // Collect months that have blog entries 077 final Collection< Calendar > months = collectMonths( engine, weblogName ); 078 int year = 0; 079 080 // Output proper HTML. 081 sb.append( "<ul>\n" ); 082 083 if( months.size() > 0 ) { 084 year = ( months.iterator().next() ).get( Calendar.YEAR ); 085 sb.append( "<li class=\"archiveyear\">" ).append( year ).append( "</li>\n" ); 086 } 087 088 for( final Calendar cal : months ) { 089 if( cal.get( Calendar.YEAR ) != year ) { 090 year = cal.get( Calendar.YEAR ); 091 sb.append( "<li class=\"archiveyear\">" ).append( year ).append( "</li>\n" ); 092 } 093 sb.append( " <li>" ); 094 sb.append( getMonthLink( cal ) ); 095 sb.append( "</li>\n" ); 096 } 097 098 sb.append( "</ul>\n" ); 099 sb.append( "</div>\n" ); 100 return sb.toString(); 101 } 102 103 private SortedSet< Calendar > collectMonths( final Engine engine, final String page ) { 104 final Comparator< Calendar > comp = new ArchiveComparator(); 105 final TreeSet<Calendar> res = new TreeSet<>( comp ); 106 107 final WeblogPlugin pl = new WeblogPlugin(); 108 109 final List< Page > blogEntries = pl.findBlogEntries( engine, page, new Date(0L), new Date() ); 110 111 for( final Page p : blogEntries ) { 112 // FIXME: Not correct, should parse page creation time. 113 final Date d = p.getLastModified(); 114 final Calendar cal = Calendar.getInstance(); 115 cal.setTime( d ); 116 res.add( cal ); 117 } 118 119 return res; 120 } 121 122 private String getMonthLink( final Calendar day ) 123 { 124 final SimpleDateFormat monthfmt = new SimpleDateFormat( "MMMM" ); 125 final String result; 126 127 if( m_monthUrlFormat == null ) { 128 result = monthfmt.format( day.getTime() ); 129 } else { 130 final Calendar cal = (Calendar)day.clone(); 131 final int firstDay = cal.getActualMinimum( Calendar.DATE ); 132 final int lastDay = cal.getActualMaximum( Calendar.DATE ); 133 134 cal.set( Calendar.DATE, lastDay ); 135 String url = m_monthUrlFormat.format( cal.getTime() ); 136 137 url = TextUtil.replaceString( url, "%d", Integer.toString( lastDay-firstDay+1 ) ); 138 139 result = "<a href=\""+url+"\">"+monthfmt.format(cal.getTime())+"</a>"; 140 } 141 142 return result; 143 144 } 145 146 147 /** 148 * This is a simple comparator for ordering weblog archive entries. 149 * Two dates in the same month are considered equal. 150 */ 151 private static class ArchiveComparator implements Comparator< Calendar > { 152 153 @Override 154 public int compare( final Calendar a, final Calendar b ) { 155 if( a == null || b == null ) { 156 throw new ClassCastException( "Invalid calendar supplied for comparison." ); 157 } 158 159 if( a.get( Calendar.YEAR ) == b.get( Calendar.YEAR ) && a.get( Calendar.MONTH ) == b.get( Calendar.MONTH ) ) { 160 return 0; 161 } 162 163 //sort recent dates first 164 return b.getTime().before( a.getTime() ) ? -1 : 1; 165 } 166 } 167 168}