James Moger
2015-11-22 ed552ba47c02779c270ffd62841d6d1048dade70
commit | author | age
a7db57 1 /*
JM 2  * Copyright 2013 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.wicket;
17
18 import java.util.Date;
19
cdb2fe 20 import com.google.inject.Inject;
JM 21 import com.google.inject.Singleton;
a7db57 22 import javax.servlet.http.HttpServletRequest;
JM 23
cc47aa 24 import org.apache.wicket.protocol.http.IWebApplicationFactory;
JM 25 import org.apache.wicket.protocol.http.WebApplication;
26 import org.apache.wicket.protocol.http.WicketFilter;
a7db57 27 import org.apache.wicket.util.string.Strings;
JM 28 import org.eclipse.jgit.lib.Repository;
29 import org.eclipse.jgit.revwalk.RevCommit;
30
db4f6b 31 import com.gitblit.IStoredSettings;
a7db57 32 import com.gitblit.Keys;
db4f6b 33 import com.gitblit.manager.IProjectManager;
JM 34 import com.gitblit.manager.IRepositoryManager;
35 import com.gitblit.manager.IRuntimeManager;
a7db57 36 import com.gitblit.models.ProjectModel;
JM 37 import com.gitblit.models.RepositoryModel;
38 import com.gitblit.utils.JGitUtils;
39 import com.gitblit.utils.StringUtils;
40
41 /**
699e71 42  *
a7db57 43  * Customization of the WicketFilter to allow smart browser-side caching of
JM 44  * some pages.
699e71 45  *
a7db57 46  * @author James Moger
JM 47  *
48  */
1b34b0 49 @Singleton
JM 50 public class GitblitWicketFilter extends WicketFilter {
699e71 51
65d5bb 52     private IStoredSettings settings;
116422 53
65d5bb 54     private IRuntimeManager runtimeManager;
cacf8b 55
65d5bb 56     private IRepositoryManager repositoryManager;
cacf8b 57
65d5bb 58     private IProjectManager projectManager;
cacf8b 59
65d5bb 60     private GitBlitWebApp webapp;
cc47aa 61
1b34b0 62     @Inject
JM 63     public GitblitWicketFilter(
64             IStoredSettings settings,
65             IRuntimeManager runtimeManager,
66             IRepositoryManager repositoryManager,
67             IProjectManager projectManager,
68             GitBlitWebApp webapp) {
69
70         this.settings = settings;
71         this.runtimeManager = runtimeManager;
72         this.repositoryManager = repositoryManager;
73         this.projectManager = projectManager;
74         this.webapp = webapp;
cc47aa 75     }
JM 76
77     @Override
78     protected IWebApplicationFactory getApplicationFactory() {
79         return new IWebApplicationFactory() {
80             @Override
81             public WebApplication createApplication(WicketFilter filter) {
82                 return webapp;
83             }
84         };
116422 85     }
JM 86
a7db57 87     /**
JM 88      * Determines the last-modified date of the requested resource.
699e71 89      *
a7db57 90      * @param servletRequest
JM 91      * @return The last modified time stamp
92      */
699e71 93     @Override
a7db57 94     protected long getLastModified(final HttpServletRequest servletRequest)    {
JM 95         final String pathInfo = getRelativePath(servletRequest);
116422 96         if (Strings.isEmpty(pathInfo)) {
a7db57 97             return -1;
116422 98         }
a7db57 99         long lastModified = super.getLastModified(servletRequest);
JM 100         if (lastModified > -1) {
101             return lastModified;
102         }
699e71 103
a7db57 104         // try to match request against registered CacheControl pages
JM 105         String [] paths = pathInfo.split("/");
699e71 106
a7db57 107         String page = paths[0];
JM 108         String repo = "";
109         String commitId = "";
110         if (paths.length >= 2) {
111             repo = paths[1];
112         }
113         if (paths.length >= 3) {
114             commitId = paths[2];
115         }
699e71 116
a7db57 117         if (!StringUtils.isEmpty(servletRequest.getParameter("r"))) {
JM 118             repo = servletRequest.getParameter("r");
119         }
120         if (!StringUtils.isEmpty(servletRequest.getParameter("h"))) {
121             commitId = servletRequest.getParameter("h");
122         }
db4f6b 123
JM 124         repo = repo.replace("%2f", "/").replace("%2F", "/").replace(settings.getChar(Keys.web.forwardSlashCharacter, '/'), '/');
a7db57 125
JM 126         GitBlitWebApp app = (GitBlitWebApp) getWebApplication();
db4f6b 127         int expires = settings.getInteger(Keys.web.pageCacheExpires, 0);
a7db57 128         if (!StringUtils.isEmpty(page) && app.isCacheablePage(page) && expires > 0) {
JM 129             // page can be cached by the browser
130             CacheControl cacheControl = app.getCacheControl(page);
db4f6b 131             Date bootDate = runtimeManager.getBootDate();
a7db57 132             switch (cacheControl.value()) {
JM 133             case ACTIVITY:
134                 // returns the last activity date of the server
db4f6b 135                 Date activityDate = repositoryManager.getLastActivityDate();
a7db57 136                 if (activityDate != null) {
JM 137                     return activityDate.after(bootDate) ? activityDate.getTime() : bootDate.getTime();
138                 }
139                 return bootDate.getTime();
140             case BOOT:
141                 // return the boot date of the server
142                 return bootDate.getTime();
143             case PROJECT:
144                 // return the latest change date for the project OR the boot date
db4f6b 145                 ProjectModel project = projectManager.getProjectModel(StringUtils.getRootPath(repo));
a7db57 146                 if (project != null) {
JM 147                     return project.lastChange.after(bootDate) ? project.lastChange.getTime() : bootDate.getTime();
148                 }
149                 break;
150             case REPOSITORY:
151                 // return the lastest change date for the repository OR the boot
152                 // date, whichever is latest
db4f6b 153                 RepositoryModel repository = repositoryManager.getRepositoryModel(repo);
a7db57 154                 if (repository != null && repository.lastChange != null) {
JM 155                     return repository.lastChange.after(bootDate) ? repository.lastChange.getTime() : bootDate.getTime();
156                 }
157                 break;
158             case COMMIT:
159                 // get the date of the specified commit
160                 if (StringUtils.isEmpty(commitId)) {
161                     // no commit id, use boot date
162                     return bootDate.getTime();
163                 } else {
699e71 164                     // last modified date is the commit date
a7db57 165                     Repository r = null;
JM 166                     try {
167                         // return the timestamp of the associated commit
db4f6b 168                         r = repositoryManager.getRepository(repo);
a7db57 169                         if (r != null) {
JM 170                             RevCommit commit = JGitUtils.getCommit(r, commitId);
171                             if (commit != null) {
172                                 Date date = JGitUtils.getCommitDate(commit);
173                                 return date.after(bootDate) ? date.getTime() : bootDate.getTime();
174                             }
175                         }
176                     } finally {
177                         if (r != null) {
178                             r.close();
179                         }
180                     }
181                 }
182                 break;
183             default:
184                 break;
185             }
699e71 186         }
a7db57 187
JM 188         return -1;
189     }
190 }