[{TableOfContents}]
!! Version Overwrite

Every time you press "SAVE", JSPWiki saves a new version of a page.
Since recently, JSPWiki only saves a new version if changes were made to the page (good ;-).

However, typical edit sequences consists of multiple edit/save/edit/save... commands 
executed till you are satisfied with the page. Which leads to a high number of page versions
with little or no added value. (look at the first 3 version of the page ;-o )

This page describes a hack of the current JSPWiki in order to limit the number of new page versions. 
It was tested on a JSPWiki,v2.3.61.
-- [DF|DirkFrederickx]

See also [IdeaSingleVersionForSavesBySameUserWithinHour]

! Approach

When the following conditions apply, the default behaviour of JSPWiki will be to overwrite the last version 
of the page instead of creating a new one.

# __The user must be logged in__. (authenticated) \\
  Anonymous or asserted users can not overwrite versions, i.e., 
  each change will be registered with new page versions (security).
# The user must be the __same as the last author__ of the page \\
  A sequence of edits by different users will be registered as different page versions
# The change of the page must happen __within one hour since the last modification__
  When subsequent edits happen with intervals of more then one hour, 
  a different page version will be created.

When all of these conditions hold, JSPWiki will overwrite the last version of the page. 
However, a checkbox will be added to the edit screen so that the user can still decide NOT to overwrite, but save the changes to a new version.

These conditions are checked when opening the edit screen (show/hide the checkbox)
and on saving the page (press save).

!! Implementation

You need to make changes to two files:
* the {{/templates/<your-template>/editors/plain.jsp}}
* the toplevel {{Edit.jsp}}

! Changes to __plain.jsp__ (TEMPLATES LEVEL)

This jsp generates the standard edit screen with the Save/Preview/Cancel buttons.
The added stuff inserts the "Overwrite version" checkbox if needed.

Add following stuff just after these three buttons:
{{{
  <%-- OVERWRITE BLOCK --%>
  <wiki:PageExists>
  <%
    java.util.Date now = new java.util.Date();       
    long anHourAgo = now.getTime() - (60*60*1000);
    String lastchange = (String) pageContext.getAttribute("lastchange",PageContext.REQUEST_SCOPE);
    long lastChangeTime = Long.parseLong( lastchange );
    String lastAuthor = context.getPage().getAuthor();
    String thisAuthor = context.getWikiSession().getUserPrincipal().getName();                           
  %>
  <wiki:UserCheck status="authenticated">
    <% if( lastAuthor.equals(thisAuthor) ) { /* should be the same author */ %>
      <% if( lastChangeTime > anHourAgo ) { /* changes within one hour */ %>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        Overwrite version: <input type="checkbox" name="overwrite" checked="checked" />
      <% } /* changes within one hour */ %>
    <% } /* should be the same author */ %>
  </wiki:UserCheck>
  </wiki:PageExists>
}}}


! Changes to __Edit.jsp__  (TOP LEVEL)

The top level {{Edit.jsp}} is responsible for the actual handling of the Edit page, 
including the actual SAVE command.

First you need to capture the status of the OVERWRITE checkbox. The following lines can be added in the beginning of the file:
{{{
  /* #####OVERWRITE checkbox##### */
  String overwrite = request.getParameter("overwrite");
}}}


Then you need to change the actual SAVING of the text. Locate following lines:
{{{
  else
  {
    wiki.saveText( wikiContext, text );
  }
}}}

and change them to 
{{{
  else
  {
    if( overwrite != null )
    {
      if( wikiSession.isAuthenticated() )
      {
        if( user.equals( wikipage.getAuthor() ) )
        {
          Date now        = new Date();       
          long anHourAgo  = now.getTime() - (60*60*1000);    
          long lastchange = 0;
          Date d = latestversion.getLastModified();
          if( d != null ) lastchange = d.getTime();
          if( lastchange > anHourAgo ) 
          {
            log.info("OVERWRITE : -- so first delete the latest version");
            wiki.deleteVersion( wikipage );
          }
        }
      }
    }
    wiki.saveText( wikiContext, text );
  }
}}}

You can see that the different checks are repeated here, to make sure
the overwrite flag is not spoofed in anyway. (paranoia;-)

Also notice how I implemented the actual overwrite: first the current version is deleted; then the new text is saved.

WARNING: I tested this only with the {{VersioningFileProvider}}. 

\\
--Gerard Perreault, 2011-02-06

We use version 2.8.4 and everything else was OK for this to work except for 2 things:
* Getting the time from the file wasn't giving the correct value, so we changed it to:
{{{
  <%-- OVERWRITE BLOCK --%>
  <wiki:PageExists>
    <%
      java.util.Date now = new java.util.Date();
      long anHourAgo = (now.getTime() - (60*60*1000));
      long lastChangeTime = 0;
      Date d = context.getPage().getLastModified();
      if( d != null ) lastChangeTime = d.getTime();
      String lastAuthor = context.getPage().getAuthor();
      String thisAuthor = context.getWikiSession().getUserPrincipal().getName();
    %>
    <!-- You can use these traces to debug, and then remove them:
       anHourAgo = <%= "" + anHourAgo%><BR>
       lastChangeTime = <%= "" + lastChangeTime%><BR>
       now = <%= "" + now%><BR>
       context.getPage().getLastModified() = <%= "" + context.getPage().getLastModified()%><BR>
    -->
    <wiki:UserCheck status="authenticated">
      <% if( lastAuthor.equals(thisAuthor) ) { /* should be the same author */ %>
        <% if( lastChangeTime > anHourAgo ) { /* changes within one hour */ %>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          Overwrite version: <input type="checkbox" name="overwrite" checked="checked" />
        <% } /* changes within one hour */ %>
      <% } /* should be the same author */ %>
    </wiki:UserCheck>
  </wiki:PageExists>
}}}

* The ''else'' section had to be changed like this:
{{{
            else
            {
                if( overwrite != null )
                {
                    if( wikiSession.isAuthenticated() )
                    {
                        if( user.equals( wikipage.getAuthor() ) )
                        {
                            Date now        = new Date();
                            long anHourAgo  = (now.getTime() - (60*60*1000));
                            long lastchange = 0;
                            Date d = latestversion.getLastModified();
                            if( d != null ) lastchange = d.getTime();
                            if( lastchange > anHourAgo )
                            {

                                WikiPage p = wiki.getPage( pagereq);

                                log.info("OVERWRITE : -- so first delete the latest version");
                                wiki.deleteVersion( p );
                                wikipage = wiki.getPage( pagereq);
                            }
                        }
                    }
                }
                wiki.saveText( wikiContext, text );
            }
}}}