/* * Created on Jun 6, 2008 * */ package com.ecyrd.jspwiki.plugin; import com.ecyrd.jspwiki.WikiContext; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import javax.servlet.http.HttpServletRequest; import com.ecyrd.jspwiki.WikiEngine; import com.ecyrd.jspwiki.WikiPage; import com.ecyrd.jspwiki.providers.ProviderException; import java.util.HashMap; import java.util.Iterator; import java.util.List; /** * A simple calendar item container and HTML printer, used by WeblogCalendarPlugin. * The majority of this code is taken from the CalendarPrinter class written by * Connie Chan. * *

This particular formatter produces a div with a string that looks like the following: *

 * << <  OCT 2008  > >>
 * su mo tu we th fr sa
 *          01 02 03 04
 * 05 06 07 08 09 10 11
 * 12 13 14 15 16 17 18
 * 19 20 21 22 23 24 25
 * 26 27 28 29 30 31   
 * 
* * *

Each day is a link to a weblog entry using the http parameters weblog.startDate * and weblog.days * * @author ebu */ public class WeblogCalendarPrinter { private int m_dayMarker; private int m_dayPseudoMarker; private int m_monthMarker; private int m_yearMarker; private String CSS_SELECTED = "selected"; private String CSS_EXISTINGENTRY = "exists"; /** Stores the cached HTML string, to prevent needless rendering. */ private String m_cached = null; /** The name of this calendar. Should correspond to a WikiPage, too. */ private String m_calendarName; /** The CSS style prefix to use for DIVs in this calendar. Default is 'calendar'. */ private String m_style = "calendar"; private WikiEngine m_engine; private WikiContext m_context; /** The WikiPage that this calendar is displayed on. */ private String m_owningPage; private boolean m_changed = false; /** * Linking mode; if LINK_TO_DAY, each day entry takes us to a day-specific WikiPage. * If LINK_TO_NAME, sets the date to the clicked day and takes us to the page * m_calendarName, which presumably contains a summary view to this calendar. */ private int m_linkMode = LINK_TO_DAY; private String m_handledQuery; // Utilities for HTML printing. private final String m_empty = " "; private final String m_space = "\n"; // private final String m_empty = "  "; // private final String m_space = " "; // A nice up arrow / home mutant hybrid. Necessitates UTF-8, bad me. private final String m_today = "(Back to Today)"; public static final int LINK_TO_DAY = 0; public static final int LINK_TO_CURRENT = 1; /** * Creates a new calendar display object that uses the given name. * The name is free-form, but we expect it to also be an existant * WikiPage, and link to it accordingly. */ public WeblogCalendarPrinter( WikiEngine wiki, WikiContext context, String name ) { m_calendarName = name; m_owningPage = name; m_engine = wiki; m_context = context; Calendar cal = Calendar.getInstance(); m_dayMarker = cal.get( Calendar.DAY_OF_MONTH ); m_dayPseudoMarker = m_dayMarker; m_monthMarker = cal.get( Calendar.MONTH ); m_yearMarker = cal.get( Calendar.YEAR ); clear(); } /** * Sets the linking mode of individual calendar days. */ public void setLinkingMode( int mode ) { m_linkMode = mode; m_changed = true; } public void clear() { m_changed = true; } /** * Sets the unique name of the calendar. This is also presumed to be the name * of a WikiPage associated with this calendar. */ public void setName( String name ) { m_calendarName = name; m_changed = true; } /** * Returns the unique(?) name of the calendar. */ public String getName() { return( m_calendarName ); } /* * Sets the year to display. * This is optimized to cause re-rendering only if the date has actually changed. */ public void setYear( String y ) { try { setYear( Integer.parseInt( y ) ); } catch( NumberFormatException e ) { } } /* * Sets the year to display. * This is optimized to cause re-rendering only if the date has actually changed. */ public void setYear( int year ) { if( m_yearMarker != year ) { m_yearMarker = year; m_changed = true; } } public int getYear() { return( m_yearMarker ); } public int getMonth() { return( m_monthMarker ); } public int getDay() { return( m_dayMarker ); } /* * Sets the css style to use for the calendar div. * If the style is x, the following CSS classes are used in the calendar view: * x, xtitle */ public void setCSSStyle( String cssStyle ) { m_style = cssStyle; m_changed = true; } /* * Sets the month to display. * This is optimized to cause re-rendering only if the date has actually changed. */ public void setMonth( String m ) { try { int month = Integer.parseInt( m ); month = month % 12; setMonth( month ); } catch( NumberFormatException e ) { } } /* * Sets the month to display. * This is optimized to cause re-rendering only if the date has actually changed. */ public void setMonth( int month ) { if( m_monthMarker != month ) { m_monthMarker = month; setDay( m_dayMarker ); // update in case of now.maxdate < previously.maxdate m_changed = true; } } /* * Sets the day to (maybe) display. * This is optimized to cause re-rendering only if the date has actually changed. * Should be called after setMonth(). */ public void setDay( String d ) { try { int day = Integer.parseInt( d ); setDay( day ); } catch( NumberFormatException e ) { } } /* * Sets the month to display. * Always causes a render update, because we're too lazy to check for an actual change. */ public void setDay( int d ) { if( m_dayMarker != d ) { m_dayMarker = d; m_changed = true; } Calendar cal = Calendar.getInstance(); cal.set( Calendar.DAY_OF_MONTH, 1 ); cal.set( Calendar.MONTH, m_monthMarker ); int max = cal.getActualMaximum( Calendar.DAY_OF_MONTH ); int p = (m_dayMarker > max ? max : m_dayMarker); if( p != m_dayPseudoMarker ) { m_dayPseudoMarker = p; m_changed = true; } } /** * Sets page the calendar is displayed on. This information is used in generating * the next/previous month/year links, so that clicking on them brings us back to * the same page, but with new calendar date info. * This is optimized to cause re-rendering only if the date has actually changed. */ public void setDisplayPage( String wikiPage ) { if( wikiPage.equals( m_owningPage ) == false ) { m_owningPage = wikiPage; m_changed = true; } } public String getDisplayPage() { return( m_owningPage ); } protected void setHandledRequest( HttpServletRequest req ) { m_handledQuery = req.getQueryString(); } public boolean requestHandled( HttpServletRequest req ) { if( req == null || m_handledQuery == null ) return( false ); String newQuery = req.getQueryString(); if( m_handledQuery == newQuery ) return( true ); if( m_handledQuery.equals( newQuery ) ) return( true ); return( false ); } SimpleDateFormat m_datefmt = new SimpleDateFormat( "ddMMyy" ); /** * Return the filename this object would use for the given date in its html output. */ public String getEntryName( Calendar date ) { return( m_calendarName + "_" + m_datefmt.format( date.getTime() ) ); } /** * Produces HTML output for a monthly view, tailored for the given page. */ public String printMonthView(WikiContext context) throws Exception { if( m_changed ) { m_context = context; Calendar marker = Calendar.getInstance(); marker.setFirstDayOfWeek( Calendar.SUNDAY ); int realMonth = marker.get( Calendar.MONTH ); int realYear = marker.get( Calendar.YEAR ); int realDay = marker.get( Calendar.DAY_OF_MONTH ); // Currently displayed month/year/day. Get before clone(), in case we did stupidities... int currMonth = m_monthMarker; int currYear = m_yearMarker; int currDay = m_dayPseudoMarker; marker.set( Calendar.MONTH, currMonth ); marker.set( Calendar.DAY_OF_MONTH, currDay ); marker.set( Calendar.YEAR, currYear ); int maxDays = marker.getActualMaximum( Calendar.DAY_OF_MONTH ); int yearDays = marker.getActualMaximum( Calendar.DAY_OF_YEAR ); // Scrollers for iterating through the days of the month. Calendar cal = (Calendar)marker.clone(); Calendar scroller = (Calendar)marker.clone(); Calendar scroller2 = (Calendar)marker.clone(); scroller2.set(Calendar.DAY_OF_MONTH, maxDays); String lastDayOfMonth = m_datefmt.format(scroller2.getTime()); scroller2.set(Calendar.MONTH, 11); scroller2.set(Calendar.DAY_OF_MONTH, 31); String lastDayOfYear = m_datefmt.format(scroller2.getTime()); cal.set( Calendar.DAY_OF_MONTH, 1 ); // 1 is start date int firstDayOfWeek = cal.get( Calendar.DAY_OF_WEEK ); // 1 is Monday. if( firstDayOfWeek < 1 ) firstDayOfWeek += 7; // Formatting for month/year in title, and days in table SimpleDateFormat monthfmt = new SimpleDateFormat( "MMM" ); SimpleDateFormat yearfmt = new SimpleDateFormat( "yyyy" ); SimpleDateFormat dayfmt = new SimpleDateFormat( "dd" ); SimpleDateFormat simpleMonthfmt = new SimpleDateFormat( "MM" ); // Shortcuts for already too long HTML string nasties. String cy = WeblogCalendarPlugin.EXT_YEAR; String cm = WeblogCalendarPlugin.EXT_MONTH; String cd = WeblogCalendarPlugin.EXT_DAY; // Target page time scroller links take to (the page this calendar is shown on). String currentURL = m_engine.getViewURL( m_owningPage ); HashMap blogEntries = getBlogEntries(context, m_owningPage); String blogParams = ""; String selectedDate = ""; try { if (m_context.getHttpParameter("weblog.startDate") != null && m_context.getHttpParameter("weblog.days") != null) { selectedDate = m_context.getHttpParameter("weblog.startDate"); blogParams = "&weblog.startDate=" + m_context.getHttpParameter("weblog.startDate") + "&weblog.days=" + m_context.getHttpParameter("weblog.days"); } } catch (Exception e) { // do nothing because http parameters must be null } StringBuffer buf = new StringBuffer(); // Start calendar div. Date-change-info is encoded in HTTP params, so the CalendarPlugin can figure them out. // buf.append( "

\n" ); buf.append( "\n" ); buf.append( "\n" ); buf.append( "\n" ); //buf.append( "" ); // Start date table. Add empty days. We don't show the previous month's days. buf.append( "\n" ); col++; } else { buf.append( m_space ); col++; } cal.add( Calendar.DAY_OF_MONTH, 1 ); } // Move to the end of the last row. while (col < 6) { buf.append( " " + m_space ); col++; } if( cal.get( Calendar.DAY_OF_WEEK ) != Calendar.SUNDAY ) { buf.append( " \n" ); } // A bit of finery: always pad to the full 6 rows (the 6th will also get a today link). // while( row++ < 5 ) // { // buf.append( "\n" ); // col = 0; // } buf.append( "\n" ); buf.append( "
\n" ); // '<<', with link to current page, previous year in this calendar buf.append( "<< " ); // '<', with link to current page, previous month in this calendar scroller.add( Calendar.MONTH, -1 ); buf.append( "<  " ); // month, with link to WikiPage m_calendarName, last day of this month, maxDays days buf.append( "" + monthfmt.format( cal.getTime() ) + " " ); // year, with link to WikiPage m_calendarName, last day of year, about 365 days buf.append( "" + yearfmt.format( cal.getTime() ) + "" ); // '>', next month, this page scroller.add( Calendar.MONTH, 2 ); buf.append( "  >" ); // '>>', next year, this page buf.append( " >>" ); buf.append( "
\n" ); //FIX: hard-coding: buf.append( "
sumotuwethfrsa
 
" ); for( int i = Calendar.SUNDAY; i < firstDayOfWeek; i++ ) // 1 for first day, again. Argh. buf.append( m_empty + m_space ); // Add dates, with style (if set), link (if set), and remember // a newline and break when the week ends (on sundays). int row = 0; // Tracks the week row we're doing. int col = 0; // Tracks the day column we're doing. while( cal.get( Calendar.MONTH ) == currMonth ) { int d = cal.get(Calendar.DAY_OF_MONTH); //String targetPageName = getEntryName( cal ); String targetPageName = m_owningPage; // By default, link to a daily entry (LINK_TO_DAY). LINK_TO_NAME provides a navigation mode, instead. if( m_linkMode == LINK_TO_CURRENT ) targetPageName = m_owningPage; String pageUrl = m_engine.getViewURL( targetPageName ); String cssClass = ""; if (blogEntries.containsKey(m_datefmt.format(cal.getTime()))) cssClass = "class=\"" + CSS_EXISTINGENTRY + "\" "; if (selectedDate.equals(m_datefmt.format(cal.getTime()))) cssClass = "class=\"" + CSS_SELECTED + "\" "; if ( cal.get( Calendar.DAY_OF_WEEK ) == Calendar.SUNDAY ) { buf.append( "
" ); col = 0; } buf.append( "" + dayfmt.format( cal.getTime() ) + "" ); // Advance row counter on sunday. Need to keep track of row and col, though. if( cal.get( Calendar.DAY_OF_WEEK ) == Calendar.SATURDAY ) { row++; buf.append( "
 
" + m_today + "
\n" ); // buf.append( "
\n" ); m_cached = buf.toString(); m_changed = false; } return( m_cached ); } private HashMap getBlogEntries (WikiContext context, String page) throws Exception{ // Used HashMap for faster searching. HashMap blogEntriesMap = new HashMap(); WeblogPlugin pl = new WeblogPlugin(); List blogEntries; try { blogEntries = pl.findBlogEntries( context.getEngine().getPageManager(), page, new Date(0L), new Date() ); } catch (ProviderException e) { throw e; } for (Iterator i = blogEntries.iterator(); i.hasNext(); ) { WikiPage p = (WikiPage) i.next(); String dateStr = p.getName().substring(p.getName().indexOf("_blogentry_") + "_blogentry_".length(), p.getName().lastIndexOf("_")); blogEntriesMap.put(dateStr,dateStr); } return blogEntriesMap; } public static void main (String[] args) { String p = "SamBurdenBlog_blogentry_300508_2"; System.out.println(p.substring(p.indexOf("_blogentry_") + "_blogentry_".length(), p.lastIndexOf("_"))); } }