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

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.

  1. 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).
  2. 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
  3. 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 );
            }

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-8) was last changed on 06-Feb-2011 20:51 by Gerard Perreault