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.tags;
020
021import org.apache.wiki.api.core.ContextEnum;
022import org.apache.wiki.api.core.Engine;
023import org.apache.wiki.api.core.Page;
024import org.apache.wiki.api.providers.WikiProvider;
025import org.apache.wiki.pages.PageManager;
026
027import javax.servlet.jsp.JspWriter;
028import java.io.IOException;
029
030/**
031 *  Writes a diff link.  Body of the link becomes the link text.
032 *  <P><B>Attributes</B></P>
033 *  <UL>
034 *    <LI>page - Page name to refer to.  Default is the current page.</LI>
035 *    <LI>version - The older of these versions.  May be an integer to
036 *        signify a version number, or the text "latest" to signify the latest version.
037 *        If not specified, will default to "latest".  May also be "previous" to signify
038 *        a version prior to this particular version.</LI>
039 *    <LI>newVersion - The newer of these versions.  Can also be "latest", or "previous".  Defaults to "latest".</LI>
040 *  </UL>
041 *
042 *  If the page does not exist, this tag will fail silently, and not evaluate
043 *  its body contents.
044 *
045 *  @since 2.0
046 */
047public class DiffLinkTag extends WikiLinkTag {
048
049    private static final long serialVersionUID = 0L;
050    public static final String VER_LATEST   = "latest";
051    public static final String VER_PREVIOUS = "previous";
052    public static final String VER_CURRENT  = "current";
053
054    private String m_version    = VER_LATEST;
055    private String m_newVersion = VER_LATEST;
056
057    @Override
058    public void initTag() {
059        super.initTag();
060        m_version = m_newVersion = VER_LATEST;
061    }
062
063    public final String getVersion()
064    {
065        return m_version;
066    }
067
068    public void setVersion( final String arg )
069    {
070        m_version = arg;
071    }
072
073    public final String getNewVersion()
074    {
075        return m_newVersion;
076    }
077
078    public void setNewVersion( final String arg )
079    {
080        m_newVersion = arg;
081    }
082
083    @Override
084    public final int doWikiStartTag() throws IOException {
085        final Engine engine = m_wikiContext.getEngine();
086        String pageName = m_pageName;
087
088        if( m_pageName == null ) {
089            if( m_wikiContext.getPage() != null ) {
090                pageName = m_wikiContext.getPage().getName();
091            } else {
092                return SKIP_BODY;
093            }
094        }
095
096        final JspWriter out = pageContext.getOut();
097
098        int r1;
099        int r2;
100
101        //  In case the page does not exist, we fail silently.
102        if( !engine.getManager( PageManager.class ).wikiPageExists( pageName ) ) {
103            return SKIP_BODY;
104        }
105
106        if( VER_LATEST.equals( getVersion() ) ) {
107            final Page latest = engine.getManager( PageManager.class ).getPage( pageName, WikiProvider.LATEST_VERSION );
108            if( latest == null ) {
109                // This may occur if matchEnglishPlurals is on, and we access the wrong page name
110                return SKIP_BODY;
111            }
112            r1 = latest.getVersion();
113        } else if( VER_PREVIOUS.equals( getVersion() ) ) {
114            r1 = m_wikiContext.getPage().getVersion() - 1;
115            r1 = Math.max( r1, 1 );
116        } else if( VER_CURRENT.equals( getVersion() ) ) {
117            r1 = m_wikiContext.getPage().getVersion();
118        } else {
119            r1 = Integer.parseInt( getVersion() );
120        }
121
122        if( VER_LATEST.equals( getNewVersion() ) ) {
123            final Page latest = engine.getManager( PageManager.class ).getPage( pageName, WikiProvider.LATEST_VERSION );
124            r2 = latest.getVersion();
125        } else if( VER_PREVIOUS.equals( getNewVersion() ) ) {
126            r2 = m_wikiContext.getPage().getVersion() - 1;
127            r2 = Math.max( r2, 1 );
128        } else if( VER_CURRENT.equals( getNewVersion() ) ) {
129            r2 = m_wikiContext.getPage().getVersion();
130        } else {
131            r2 = Integer.parseInt( getNewVersion() );
132        }
133
134        final String url = m_wikiContext.getURL( ContextEnum.PAGE_DIFF.getRequestContext(), pageName, "r1="+r1+"&amp;r2="+r2 );
135        switch( m_format ) {
136          case ANCHOR:
137            out.print("<a href=\""+url+"\">");
138            break;
139          case URL:
140            out.print( url );
141            break;
142        }
143
144        return EVAL_BODY_INCLUDE;
145    }
146
147}