James Moger
2013-07-19 a7db5748622e1b322b67fbbd72aed4e6efff7690
Implemented optional page caching
2 files added
32 files modified
437 ■■■■■ changed files
releases.moxie 6 ●●●● patch | view | raw | blame | history
src/main/distrib/data/gitblit.properties 7 ●●●●● patch | view | raw | blame | history
src/main/java/WEB-INF/web.xml 2 ●●● patch | view | raw | blame | history
src/main/java/com/gitblit/GitBlit.java 27 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/LogoServlet.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/PagesServlet.java 3 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/CacheControl.java 40 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/GitBlitWebApp.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/GitblitWicketFilter.java 145 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/ActivityPage.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/BasePage.java 67 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/BlamePage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/BlobPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/BranchesPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java 8 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/CommitPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/DocsPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/GitSearchPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/HistoryPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/LogPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/MarkdownPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/MetricsPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/OverviewPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/PatchPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/ProjectPage.java 23 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/ReflogPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/RepositoriesPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/RepositoryPage.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/SummaryPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/TagPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/TagsPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/TreePage.java 3 ●●●●● patch | view | raw | blame | history
releases.moxie
@@ -20,14 +20,18 @@
    changes:
    - updated Chinese translation
    - updated Dutch translation
    additions: ~
    additions:
    - Added optional browser-side page caching using Last-Modified and Cache-Control for the dashboard, activity, project, and several repository pages
    dependencyChanges: ~
    settings:
    - { name: 'web.pageCacheExpires', defaultValue: 0 }
    contributors:
    - Rainer Alföldi 
    - Liyu Wang
    - Jeroen Baten
    - James Moger
    - Stardrad Yin
    - Chad Horohoe
}
#
src/main/distrib/data/gitblit.properties
@@ -616,6 +616,13 @@
# BASEFOLDER
web.robots.txt = ${baseFolder}/robots.txt
# The number of minutes to cache a page in the browser since the last request.
# The default value is 0 minutes.  A value <= 0 disables all page caching which
# is the default behavior for Gitblit <= 1.3.0.
#
# SINCE 1.3.1
web.pageCacheExpires = 0
# If true, the web ui layout will respond and adapt to the browser's dimensions.
# if false, the web ui will use a 940px fixed-width layout.
# http://twitter.github.com/bootstrap/scaffolding.html#responsive
src/main/java/WEB-INF/web.xml
@@ -256,7 +256,7 @@
    <filter>
        <filter-name>wicketFilter</filter-name>
        <filter-class>
            org.apache.wicket.protocol.http.WicketFilter
            com.gitblit.wicket.GitblitWicketFilter
        </filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
src/main/java/com/gitblit/GitBlit.java
@@ -232,6 +232,33 @@
        }
        return gitblit;
    }
    /**
     * Returns the boot date of the Gitblit server.
     *
     * @return the boot date of Gitblit
     */
    public static Date getBootDate() {
        return self().serverStatus.bootDate;
    }
    /**
     * Returns the most recent change date of any repository served by Gitblit.
     *
     * @return a date
     */
    public static Date getLastActivityDate() {
        Date date = null;
        for (String name : self().getRepositoryList()) {
            Repository r = self().getRepository(name);
            Date lastChange = JGitUtils.getLastChange(r).when;
            r.close();
            if (lastChange != null && (date == null || lastChange.after(date))) {
                date = lastChange;
            }
        }
        return date;
    }
    /**
     * Determine if this is the GO variant of Gitblit.
src/main/java/com/gitblit/LogoServlet.java
@@ -76,6 +76,7 @@
                contentType = "image/png";
            }
            response.setContentType(contentType);
            response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");
            OutputStream os = response.getOutputStream();
            byte[] buf = new byte[4096];
            int bytesRead = is.read(buf);
src/main/java/com/gitblit/PagesServlet.java
@@ -141,7 +141,6 @@
                r.close();
                return;
            }
            response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime());
            String [] encodings = GitBlit.getEncodings();
@@ -226,6 +225,8 @@
            try {
                // output the content
                response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");
                response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime());
                response.getOutputStream().write(content);
                response.flushBuffer();
            } catch (Throwable t) {
src/main/java/com/gitblit/wicket/CacheControl.java
New file
@@ -0,0 +1,40 @@
/*
 * Copyright 2013 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
 * Page attribute to control what date as last-modified for the browser cache.
 *
 * http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching
 * https://developers.google.com/speed/docs/best-practices/caching
 *
 * @author James Moger
 *
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheControl {
    public static enum LastModified {
        BOOT, ACTIVITY, PROJECT, REPOSITORY, COMMIT, NONE
    }
    LastModified value() default LastModified.NONE;
}
src/main/java/com/gitblit/wicket/GitBlitWebApp.java
@@ -15,7 +15,9 @@
 */
package com.gitblit.wicket;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.wicket.Application;
import org.apache.wicket.Page;
@@ -70,6 +72,8 @@
public class GitBlitWebApp extends WebApplication {
    public final static Class<? extends BasePage> HOME_PAGE_CLASS = MyDashboardPage.class;
    private final Map<String, CacheControl> cacheablePages = new HashMap<String, CacheControl>();
    
    @Override
    public void init() {
@@ -149,6 +153,12 @@
            parameters = new String[] {};
        }
        mount(new GitblitParamUrlCodingStrategy(location, clazz, parameters));
        // map the mount point to the cache control definition
        if (clazz.isAnnotationPresent(CacheControl.class)) {
            CacheControl cacheControl = clazz.getAnnotation(CacheControl.class);
            cacheablePages.put(location.substring(1), cacheControl);
        }
    }
    @Override
@@ -156,6 +166,14 @@
        return HOME_PAGE_CLASS;
    }
    
    public boolean isCacheablePage(String mountPoint) {
        return cacheablePages.containsKey(mountPoint);
    }
    public CacheControl getCacheControl(String mountPoint) {
        return cacheablePages.get(mountPoint);
    }
    @Override
    public final Session newSession(Request request, Response response) {
        GitBlitWebSession gitBlitWebSession = new GitBlitWebSession(request);
src/main/java/com/gitblit/wicket/GitblitWicketFilter.java
New file
@@ -0,0 +1,145 @@
/*
 * Copyright 2013 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.protocol.http.WicketFilter;
import org.apache.wicket.util.string.Strings;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
/**
 *
 * Customization of the WicketFilter to allow smart browser-side caching of
 * some pages.
 *
 * @author James Moger
 *
 */
public class GitblitWicketFilter extends WicketFilter {
    /**
     * Determines the last-modified date of the requested resource.
     *
     * @param servletRequest
     * @return The last modified time stamp
     */
    protected long getLastModified(final HttpServletRequest servletRequest)    {
        final String pathInfo = getRelativePath(servletRequest);
        if (Strings.isEmpty(pathInfo))
            return -1;
        long lastModified = super.getLastModified(servletRequest);
        if (lastModified > -1) {
            return lastModified;
        }
        // try to match request against registered CacheControl pages
        String [] paths = pathInfo.split("/");
        String page = paths[0];
        String repo = "";
        String commitId = "";
        if (paths.length >= 2) {
            repo = paths[1];
        }
        if (paths.length >= 3) {
            commitId = paths[2];
        }
        if (!StringUtils.isEmpty(servletRequest.getParameter("r"))) {
            repo = servletRequest.getParameter("r");
        }
        if (!StringUtils.isEmpty(servletRequest.getParameter("h"))) {
            commitId = servletRequest.getParameter("h");
        }
        repo = repo.replace("%2f", "/").replace("%2F", "/").replace(GitBlit.getChar(Keys.web.forwardSlashCharacter, '/'), '/');
        GitBlitWebApp app = (GitBlitWebApp) getWebApplication();
        int expires = GitBlit.getInteger(Keys.web.pageCacheExpires, 0);
        if (!StringUtils.isEmpty(page) && app.isCacheablePage(page) && expires > 0) {
            // page can be cached by the browser
            CacheControl cacheControl = app.getCacheControl(page);
            Date bootDate = GitBlit.getBootDate();
            switch (cacheControl.value()) {
            case ACTIVITY:
                // returns the last activity date of the server
                Date activityDate = GitBlit.getLastActivityDate();
                if (activityDate != null) {
                    return activityDate.after(bootDate) ? activityDate.getTime() : bootDate.getTime();
                }
                return bootDate.getTime();
            case BOOT:
                // return the boot date of the server
                return bootDate.getTime();
            case PROJECT:
                // return the latest change date for the project OR the boot date
                ProjectModel project = GitBlit.self().getProjectModel(StringUtils.getRootPath(repo));
                if (project != null) {
                    return project.lastChange.after(bootDate) ? project.lastChange.getTime() : bootDate.getTime();
                }
                break;
            case REPOSITORY:
                // return the lastest change date for the repository OR the boot
                // date, whichever is latest
                RepositoryModel repository = GitBlit.self().getRepositoryModel(repo);
                if (repository != null && repository.lastChange != null) {
                    return repository.lastChange.after(bootDate) ? repository.lastChange.getTime() : bootDate.getTime();
                }
                break;
            case COMMIT:
                // get the date of the specified commit
                if (StringUtils.isEmpty(commitId)) {
                    // no commit id, use boot date
                    return bootDate.getTime();
                } else {
                    // last modified date is the commit date
                    Repository r = null;
                    try {
                        // return the timestamp of the associated commit
                        r = GitBlit.self().getRepository(repo);
                        if (r != null) {
                            RevCommit commit = JGitUtils.getCommit(r, commitId);
                            if (commit != null) {
                                Date date = JGitUtils.getCommitDate(commit);
                                return date.after(bootDate) ? date.getTime() : bootDate.getTime();
                            }
                        }
                    } finally {
                        if (r != null) {
                            r.close();
                        }
                    }
                }
                break;
            default:
                break;
            }
        }
        return -1;
    }
}
src/main/java/com/gitblit/wicket/pages/ActivityPage.java
@@ -35,7 +35,9 @@
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.ActivityUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.PageRegistration;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.PageRegistration.DropDownMenuItem;
import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.WicketUtils;
@@ -52,6 +54,8 @@
 * @author James Moger
 * 
 */
@CacheControl(LastModified.ACTIVITY)
public class ActivityPage extends RootPage {
    public ActivityPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/BasePage.java
@@ -40,7 +40,10 @@
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.protocol.http.RequestUtils;
import org.apache.wicket.protocol.http.WebResponse;
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
import org.apache.wicket.util.time.Duration;
import org.apache.wicket.util.time.Time;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,6 +59,7 @@
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils;
@@ -121,7 +125,68 @@
            Application.get().getMarkupSettings().setStripWicketTags(false);
        }
        super.onAfterRender();
    }
    }
    @Override
    protected void setHeaders(WebResponse response)    {
        int expires = GitBlit.getInteger(Keys.web.pageCacheExpires, 0);
        if (expires > 0) {
            // pages are personalized for the authenticated user so they must be
            // marked private to prohibit proxy servers from caching them
            response.setHeader("Cache-Control", "private, must-revalidate");
            setLastModified();
        } else {
            // use default Wicket caching behavior
            super.setHeaders(response);
        }
    }
    /**
     * Sets the last-modified header date, if appropriate, for this page.  The
     * date used is determined by the CacheControl annotation.
     *
     */
    protected void setLastModified() {
        if (getClass().isAnnotationPresent(CacheControl.class)) {
            CacheControl cacheControl = getClass().getAnnotation(CacheControl.class);
            switch (cacheControl.value()) {
            case ACTIVITY:
                setLastModified(GitBlit.getLastActivityDate());
                break;
            case BOOT:
                setLastModified(GitBlit.getBootDate());
                break;
            case NONE:
                break;
            default:
                logger.warn(getClass().getSimpleName() + ": unhandled LastModified type " + cacheControl.value());
                break;
            }
        }
    }
    /**
     * Sets the last-modified header field and the expires field.
     *
     * @param when
     */
    protected final void setLastModified(Date when) {
        if (when == null) {
            return;
        }
        if (when.before(GitBlit.getBootDate())) {
            // last-modified can not be before the Gitblit boot date
            // this helps ensure that pages are properly refreshed after a
            // server config change
            when = GitBlit.getBootDate();
        }
        int expires = GitBlit.getInteger(Keys.web.pageCacheExpires, 0);
        WebResponse response = (WebResponse) getResponse();
        response.setLastModifiedTime(Time.valueOf(when));
        response.setDateHeader("Expires", System.currentTimeMillis() + Duration.minutes(expires).getMilliseconds());
    }
    protected void setupPage(String repositoryName, String pageName) {
        String siteName = GitBlit.getString(Keys.web.siteName, Constants.NAME);
src/main/java/com/gitblit/wicket/pages/BlamePage.java
@@ -37,11 +37,14 @@
import com.gitblit.utils.DiffUtils;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.CommitHeaderPanel;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
@CacheControl(LastModified.BOOT)
public class BlamePage extends RepositoryPage {
    public BlamePage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java
@@ -27,10 +27,13 @@
import com.gitblit.utils.DiffUtils.DiffOutputType;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.CommitHeaderPanel;
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
@CacheControl(LastModified.BOOT)
public class BlobDiffPage extends RepositoryPage {
    public BlobDiffPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/BlobPage.java
@@ -32,11 +32,14 @@
import com.gitblit.Keys;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.ExternalImage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.CommitHeaderPanel;
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
@CacheControl(LastModified.BOOT)
public class BlobPage extends RepositoryPage {
    protected String fileExtension;
src/main/java/com/gitblit/wicket/pages/BranchesPage.java
@@ -17,8 +17,11 @@
import org.apache.wicket.PageParameters;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.BranchesPanel;
@CacheControl(LastModified.REPOSITORY)
public class BranchesPage extends RepositoryPage {
    public BranchesPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java
@@ -16,7 +16,6 @@
package com.gitblit.wicket.pages;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.wicket.PageParameters;
@@ -30,22 +29,21 @@
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.Constants;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
import com.gitblit.models.PathModel.PathChangeModel;
import com.gitblit.models.GitNote;
import com.gitblit.models.SubmoduleModel;
import com.gitblit.utils.DiffUtils;
import com.gitblit.utils.DiffUtils.DiffOutputType;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.CommitHeaderPanel;
import com.gitblit.wicket.panels.CommitLegendPanel;
import com.gitblit.wicket.panels.GravatarImage;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.RefsPanel;
@CacheControl(LastModified.BOOT)
public class CommitDiffPage extends RepositoryPage {
    public CommitDiffPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/CommitPage.java
@@ -37,6 +37,8 @@
import com.gitblit.models.PathModel.PathChangeModel;
import com.gitblit.models.SubmoduleModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.CommitHeaderPanel;
import com.gitblit.wicket.panels.CommitLegendPanel;
@@ -45,6 +47,7 @@
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.RefsPanel;
@CacheControl(LastModified.BOOT)
public class CommitPage extends RepositoryPage {
    public CommitPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/DocsPage.java
@@ -30,9 +30,12 @@
import com.gitblit.models.PathModel;
import com.gitblit.utils.ByteFormat;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.LinkPanel;
@CacheControl(LastModified.REPOSITORY)
public class DocsPage extends RepositoryPage {
    public DocsPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/GitSearchPage.java
@@ -19,9 +19,12 @@
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import com.gitblit.Constants;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.SearchPanel;
@CacheControl(LastModified.REPOSITORY)
public class GitSearchPage extends RepositoryPage {
    public GitSearchPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/HistoryPage.java
@@ -18,9 +18,12 @@
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.HistoryPanel;
@CacheControl(LastModified.REPOSITORY)
public class HistoryPage extends RepositoryPage {
    public HistoryPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/LogPage.java
@@ -19,9 +19,12 @@
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.LogPanel;
@CacheControl(LastModified.REPOSITORY)
public class LogPage extends RepositoryPage {
    public LogPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/MarkdownPage.java
@@ -29,8 +29,11 @@
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
@CacheControl(LastModified.BOOT)
public class MarkdownPage extends RepositoryPage {
    public MarkdownPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/MetricsPage.java
@@ -40,9 +40,12 @@
import com.gitblit.models.Metric;
import com.gitblit.utils.MetricUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.charting.SecureChart;
@CacheControl(LastModified.REPOSITORY)
public class MetricsPage extends RepositoryPage {
    public MetricsPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java
@@ -43,11 +43,14 @@
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.FilterableProjectList;
import com.gitblit.wicket.panels.FilterableRepositoryList;
@CacheControl(LastModified.ACTIVITY)
public class MyDashboardPage extends DashboardPage {
    public MyDashboardPage() {
src/main/java/com/gitblit/wicket/pages/OverviewPage.java
@@ -34,8 +34,10 @@
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.charting.GoogleChart;
import com.gitblit.wicket.charting.GoogleCharts;
import com.gitblit.wicket.charting.GoogleLineChart;
@@ -45,6 +47,7 @@
import com.gitblit.wicket.panels.RepositoryUrlPanel;
import com.gitblit.wicket.panels.TagsPanel;
@CacheControl(LastModified.REPOSITORY)
public class OverviewPage extends RepositoryPage {
    public OverviewPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/PatchPage.java
@@ -25,9 +25,12 @@
import com.gitblit.utils.DiffUtils;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils;
@CacheControl(LastModified.BOOT)
public class PatchPage extends WebPage {
    public PatchPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/ProjectPage.java
@@ -33,6 +33,8 @@
import com.gitblit.models.UserModel;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
@@ -42,6 +44,7 @@
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.FilterableRepositoryList;
@CacheControl(LastModified.PROJECT)
public class ProjectPage extends DashboardPage {
    
    List<ProjectModel> projectModels = new ArrayList<ProjectModel>();
@@ -60,6 +63,26 @@
        return RepositoriesPage.class;
    }
    @Override
    protected void setLastModified() {
        if (getClass().isAnnotationPresent(CacheControl.class)) {
            CacheControl cacheControl = getClass().getAnnotation(CacheControl.class);
            switch (cacheControl.value()) {
            case PROJECT:
                String projectName = WicketUtils.getProjectName(getPageParameters());
                if (!StringUtils.isEmpty(projectName)) {
                    ProjectModel project = getProjectModel(projectName);
                    if (project != null) {
                        setLastModified(project.lastChange);
                    }
                }
                break;
            default:
                super.setLastModified();
            }
        }
    }
    private void setup(PageParameters params) {
        setupPage("", "");
        // check to see if we should display a login message
src/main/java/com/gitblit/wicket/pages/ReflogPage.java
@@ -18,9 +18,12 @@
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.ReflogPanel;
@CacheControl(LastModified.REPOSITORY)
public class ReflogPage extends RepositoryPage {
    public ReflogPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/RepositoriesPage.java
@@ -33,13 +33,16 @@
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.PageRegistration;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.PageRegistration.DropDownMenuItem;
import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.RepositoriesPanel;
@CacheControl(LastModified.ACTIVITY)
public class RepositoriesPage extends RootPage {
    public RepositoriesPage() {
src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
@@ -19,6 +19,7 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -63,6 +64,7 @@
import com.gitblit.utils.RefLogUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TicgitUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.PageRegistration;
import com.gitblit.wicket.PageRegistration.OtherPageLink;
@@ -572,6 +574,30 @@
        setupPage(repositoryName, "/ " + getPageName());
        super.onBeforeRender();
    }
    @Override
    protected void setLastModified() {
        if (getClass().isAnnotationPresent(CacheControl.class)) {
            CacheControl cacheControl = getClass().getAnnotation(CacheControl.class);
            switch (cacheControl.value()) {
            case REPOSITORY:
                RepositoryModel repository = getRepositoryModel();
                if (repository != null) {
                    setLastModified(repository.lastChange);
                }
                break;
            case COMMIT:
                RevCommit commit = getCommit();
                if (commit != null) {
                    Date commitDate = JGitUtils.getCommitDate(commit);
                    setLastModified(commitDate);
                }
                break;
            default:
                super.setLastModified();
            }
        }
    }
    protected PageParameters newRepositoryParameter() {
        return WicketUtils.newRepositoryParameter(repositoryName);
src/main/java/com/gitblit/wicket/pages/SummaryPage.java
@@ -50,8 +50,10 @@
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.charting.SecureChart;
import com.gitblit.wicket.panels.BranchesPanel;
import com.gitblit.wicket.panels.LinkPanel;
@@ -59,6 +61,7 @@
import com.gitblit.wicket.panels.RepositoryUrlPanel;
import com.gitblit.wicket.panels.TagsPanel;
@CacheControl(LastModified.REPOSITORY)
public class SummaryPage extends RepositoryPage {
    public SummaryPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/TagPage.java
@@ -28,11 +28,14 @@
import com.gitblit.models.RefModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.GravatarImage;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.RefsPanel;
@CacheControl(LastModified.BOOT)
public class TagPage extends RepositoryPage {
    public TagPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/TagsPage.java
@@ -17,8 +17,11 @@
import org.apache.wicket.PageParameters;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.panels.TagsPanel;
@CacheControl(LastModified.REPOSITORY)
public class TagsPage extends RepositoryPage {
    public TagsPage(PageParameters params) {
src/main/java/com/gitblit/wicket/pages/TreePage.java
@@ -33,12 +33,15 @@
import com.gitblit.models.SubmoduleModel;
import com.gitblit.utils.ByteFormat;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.CommitHeaderPanel;
import com.gitblit.wicket.panels.CompressedDownloadsPanel;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
@CacheControl(LastModified.BOOT)
public class TreePage extends RepositoryPage {
    public TreePage(PageParameters params) {