James Moger
2014-06-09 ca4d98678c20e4033fdaca09ecbbf0f5952e0b84
commit | author | age
c5dfd6 1 ## Extension Points
JM 2
3 Gitblit offers several extension points for enhancing and customizing it's runtime behavior.
4
2d73a0 5 Each available extension point has a sample implementation in the [gitblit-cookbook-plugin (Maven project)](https://github.com/gitblit/gitblit-cookbook-plugin).
JM 6
7 **NOTE:**
8 Gitblit does not yet offer a comprehensize dependency injection architecture.  This will be addressed in a subsequent release.  For now you may access all of Gitblit's core managers through a static singleton app context:
9
10 ```java
11 import com.gitblit.extensions.GitblitPlugin;
12 import com.gitblit.servlet.GitblitContext;
13 import com.gitblit.manager.IRuntimeManager;
14 import com.gitblit.manager.IUserManager;
15 import com.gitblit.manager.IAuthenticationManager;
16 import com.gitblit.manager.INotificationManager;
17 import com.gitblit.manager.IRepositoryManager;
18 import com.gitblit.manager.IProjectManager;
19 import com.gitblit.manager.IFederationManager;
20 import com.gitblit.manager.IPluginManager;
21 import com.gitblit.manager.IGitblit;
cf4004 22 import ro.fortsoft.pf4j.Version;
2d73a0 23
JM 24 public class ExamplePlugin extends GitblitPlugin {
25
26     @Override
27     public void start() {
28         IRuntimeManager runtime = GitblitContext.getManager(IRuntimeManager.class);
29         IUserManager users = GitblitContext.getManager(IUserManager.class);
30         IAuthenticationManager auth = GitblitContext.getManager(IAuthenticationManager.class);
31         INotificationManager notifications = GitblitContext.getManager(INotificationManager.class);
32         IRepositoryManager repos = GitblitContext.getManager(IRepositoryManager.class);
33         IProjectManager projects = GitblitContext.getManager(IProjectManager.class);
34         IFederationManager federation = GitblitContext.getManager(IFederationManager.class);
35         IPluginManager plugins = GitblitContext.getManager(IPluginManager.class);
36         IGitblit gitblit = GitblitContext.getManager(IGitblit.class);
37     }
cf4004 38
JM 39     @Override
40     public void stop() {
41     }
42
43     @Override
44     public void onInstall() {
45     }
46
47     @Override
48     public void onUpgrade(Version oldVersion) {
49     }
50
51     @Override
52     public void onUninstall() {
53     }
2d73a0 54 }
7a401a 55
JM 56 /**
c59584 57  * You can also create Webapp plugins that register pages.
7a401a 58  */
JM 59 public class ExampleWicketPlugin extends GitblitWicketPlugin {
60     @Override
61     public void start() {
62     }
63
64     @Override
65     public void stop() {
66     }
67
68     @Override
69     public void onInstall() {
70     }
71
72     @Override
73     public void onUpgrade(Version oldVersion) {
74     }
75
76     @Override
77     public void onUninstall() {
78     }
79
80     @Override
81     protected void init(GitblitWicketApp app) {
82         app.mount("/logo", LogoPage.class);
83         app.mount("/hello", HelloWorldPage.class);
84     }
85 }
2d73a0 86 ```
c5dfd6 87
JM 88 ### SSH Dispatch Command
89
90 *SINCE 1.5.0*
91
2d73a0 92 You can provide your own custom SSH command hierarchies by subclassing the *DispatchCommand* class.
c5dfd6 93
JM 94 ```java
95 import ro.fortsoft.pf4j.Extension;
2d73a0 96 import org.kohsuke.args4j.Option;
JM 97 import org.slf4j.Logger;
98 import org.slf4j.LoggerFactory;
c5dfd6 99 import com.gitblit.models.UserModel;
JM 100 import com.gitblit.transport.ssh.commands.CommandMetaData;
101 import com.gitblit.transport.ssh.commands.DispatchCommand;
2d73a0 102 import com.gitblit.transport.ssh.commands.UsageExample;
c5dfd6 103
JM 104 @Extension
105 @CommandMetaData(name = "mycommands", description = "Sample SSH dispatcher")
106 public class MyDispatcher extends DispatchCommand {
107
108     @Override
8cbdf3 109     protected void setup() {
c5dfd6 110         // commands in this dispatcher
8cbdf3 111         register(CommandA.class);
JM 112         register(CommandB.class);
c5dfd6 113
JM 114         // nested dispatchers
8cbdf3 115         register(SubDispatcher1.class);
JM 116         register(SubDispatcher2.class);
c5dfd6 117     }
2d73a0 118
JM 119     @CommandMetaData(name = "commanda", aliases = { "ca" }, description = "description of command a")
120     @UsageExample(syntax = "${cmd} --myflag", description = "description of commanda with --myflag")
121     public static class CommandA extends SshCommand {
122
123         protected final Logger log = LoggerFactory.getLogger(getClass());
124
125         @Option(name = "--myflag", aliases = { "-m" }, usage = "enable myflag")
126         boolean myflag;
127
128         @Override
129         public void run() throws Failure {
130             if (myflag) {
131                 log.info("Run with --myflag");
132             } else {
133                 log.info("Run without --myflag");
134             }
135         }
136     }
c5dfd6 137 }
JM 138 ```
139
140 ### Pre- and Post- Receive Hook
141
142 *SINCE 1.5.0*
143
144 You can provide your own custom pre and/or post receive hooks by subclassing the *ReceiveHook* class.
145
146 ```java
147 import com.gitblit.extensions.ReceiveHook;
148 import java.util.Collection;
149 import org.eclipse.jgit.transport.ReceiveCommand;
150 import ro.fortsoft.pf4j.Extension;
151
152 @Extension
153 public class MyReceiveHook extends ReceiveHook {
154
155     @Override
156     public void onPreReceive(GitblitReceivePack receivePack, Collection<ReceiveCommand> commands) {
157     }
158
159     @Override
160     public void onPostReceive(GitblitReceivePack receivePack, Collection<ReceiveCommand> commands) {
161     }
162 }
163
164 ```
165
166 ### Patchset Hook
167
168 *SINCE 1.5.0*
169
170 You can provide your own custom patchset hook by subclassing the *PatchsetHook* class.
171
172 ```java
173 import com.gitblit.extensions.PatchsetHook;
174 import com.gitblit.models.TicketModel;
175 import ro.fortsoft.pf4j.Extension;
176
177 @Extension
178 public class MyPatchsetHook extends PatchsetHook {
179
180     @Override
181     public void onNewPatchset(TicketModel ticket) {
182     }
183
184     @Override
185     public void onUpdatePatchset(TicketModel ticket) {
186     }
187
188     @Override
189     public void onMergePatchset(TicketModel ticket) {
190     }
191 }
192 ```
193
194 ### Ticket Hook
195
196 *SINCE 1.5.0*
197
198 You can provide your own custom ticket hook by subclassing the *TicketHook* class.
199
200 ```java
201 import com.gitblit.extensions.TicketHook;
202 import com.gitblit.models.TicketModel;
203 import com.gitblit.models.TicketModel.Change;
204 import ro.fortsoft.pf4j.Extension;
205
206 @Extension
207 public class MyTicketHook extends TicketHook {
208
209     @Override
210     public void onNewTicket(TicketModel ticket) {
211     }
212
213     @Override
214     public void onUpdateTicket(TicketModel ticket, Change change) {
215     }
216 }
217 ```
218
ec2456 219 ### Request Filter
DO 220
221 *SINCE 1.6.0*
222
223 You can provide your own custom request filter by subclassing the *HttpRequestFilter* class.
224
225 ```java
226 import com.gitblit.extensions.HttpRequestFilter;
227 import ro.fortsoft.pf4j.Extension;
228
229 @Extension
230 public class MyRequestFilter extends HttpRequestFilter {
231
232     @Override
233     public void doFilter(ServletRequest request, ServletResponse response,
234             FilterChain chain) throws IOException, ServletException {
235     }
236 }
237 ```
238
859deb 239 ### User Menu Items
856f3f 240
JM 241 *SINCE 1.6.0*
242
859deb 243 You can provide your own user menu items by subclassing the *UserMenuExtension* class.
856f3f 244
JM 245 ```java
246 import java.util.Arrays;
247 import java.util.List;
248 import ro.fortsoft.pf4j.Extension;
859deb 249 import com.gitblit.extensions.UserMenuExtension;
856f3f 250 import com.gitblit.models.Menu.ExternalLinkMenuItem;
JM 251 import com.gitblit.models.Menu.MenuItem;
252 import com.gitblit.models.UserModel;
253
254 @Extension
859deb 255 public class MyUserMenuContributor extends UserMenuExtension {
856f3f 256
JM 257     @Override
258     public List<MenuItem> getMenuItems(UserModel user) {
7a401a 259         MenuItem item = new ExternalLinkMenuItem("Github", String.format("https://github.com/%s", user.username));
JM 260         return Arrays.asList(item);
261     }
262 }
263 ```
264
265 ### Navigation Links
266
267 *SINCE 1.6.0*
268
269 You can provide your own top-level navigation links by subclassing the *NavLinkExtension* class.
270
271 ```java
272 import java.util.Arrays;
273 import java.util.List;
274 import ro.fortsoft.pf4j.Extension;
275 import com.gitblit.extensions.NavLinkExtension;
276 import com.gitblit.models.UserModel;
277
278 @Extension
279 public class MyNavLink extends NavLinkExtension {
280
281     @Override
282     public List<NavLink> getNavLinks(UserModel user) {
283         NavLink link = new ExternalLinkMenuItem("Github", String.format("https://github.com/%s", user.username));
284         return Arrays.asList(link);
856f3f 285     }
JM 286 }
287 ```
c59584 288
ca4d98 289 ### Server Lifecycle Listener
c59584 290
JM 291 *SINCE 1.6.0*
292
293 You can provide a lifecycle listener to be notified when Gitblit has completely started and just before Gitblit is gracefully terminated.
294
295 ```java
296 import org.slf4j.Logger;
297 import org.slf4j.LoggerFactory;
298 import ro.fortsoft.pf4j.Extension;
299 import com.gitblit.extensions.LifeCycleListener;
300
301 @Extension
302 public class MyLifeCycleListener extends LifeCycleListener {
303
304     final Logger log = LoggerFactory.getLogger(getClass());
305     
306     @Override
307     public void onStartup() {
308         log.info("Gitblit is Ready!!");
309     }
310
311     @Override
312     public void onShutdown() {
313         log.info("Gitblit is Going Down!!");
314     }
315 }
ca4d98 316 ```
JM 317
318 ### Repository Lifecycle Listener
319
320 *SINCE 1.6.0*
321
322 You can provide a lifecycle listener to be notified when Gitblit has created or deleted a repository.
323
324 ```java
325 import org.slf4j.Logger;
326 import org.slf4j.LoggerFactory;
327 import ro.fortsoft.pf4j.Extension;
328 import com.gitblit.extensions.RepositoryLifeCycleListener;
329 import com.gitblit.models.RepositoryModel;
330
331 @Extension
332 public class MyRepoLifeCycleListener extends RepositoryLifeCycleListener {
333
334     final Logger log = LoggerFactory.getLogger(getClass());
335     
336     @Override
337     public void onCreation(RepositoryModel repo) {
338         log.info("Gitblit created {}", repo);
339     }
340
341     @Override
342     public void onDeletion(RepositoryModel repo) {
343         log.info("Gitblit deleted {}", repo);
344     }
345 }
346 ```
347
348 ### User/Team Lifecycle Listener
349
350 *SINCE 1.6.0*
351
352 You can provide a lifecycle listener to be notified when Gitblit has created or deleted a user or a team.
353
354 ```java
355 import org.slf4j.Logger;
356 import org.slf4j.LoggerFactory;
357 import ro.fortsoft.pf4j.Extension;
358 import com.gitblit.extensions.UserTeamLifeCycleListener;
359 import com.gitblit.models.TeamModel;
360 import com.gitblit.models.UserModel;
361
362 @Extension
363 public class MyUserTeamLifeCycleListener extends UserTeamLifeCycleListener {
364
365     final Logger log = LoggerFactory.getLogger(getClass());
366     
367     @Override
368     public void onCreation(UserModel user) {
369         log.info("Gitblit created user {}", user);
370     }
371
372     @Override
373     public void onDeletion(UserModel user) {
374         log.info("Gitblit deleted user {}", user);
375     }
376
377     @Override
378     public void onCreation(TeamModel team) {
379         log.info("Gitblit created team {}", team);
380     }
381
382     @Override
383     public void onDeletion(TeamModel team) {
384         log.info("Gitblit deleted team {}", team);
385     }
386 }
387 ```