Add plugins/extension infrastructure
Plugins are stored in `${baseFolder}/plugins` and are loaded
during startup by the PluginManager.
A plugin defines it's metadata in META-INF/MANIFEST.MF:
Plugin-Class: com.gitblit.plugins.cookbook.CookbookPlugin
Plugin-Dependencies: foo, bar
Plugin-Id: gitblit-plugin
Plugin-Provider: John Doe
Plugin-Version: 1.0
Plugins can define extension points that can be implemented
by other plugins and they can depend on other plugins:
Plugin-Dependencies: foo, bar
During the load phase, a directed acyclic graph is built and the loading
order of the dependency chain is reversed using a topological sort;
parent followed by children. The parent plugin classloader is the
combined classloader of all parent plugins.
Change-Id: I738821fa2bff02a5dbe339a944cc7e3c4dd8e299
2 files added
13 files modified
| | |
| | | <classpathentry kind="lib" path="ext/args4j-2.0.26.jar" sourcepath="ext/src/args4j-2.0.26.jar" /> |
| | | <classpathentry kind="lib" path="ext/jedis-2.3.1.jar" sourcepath="ext/src/jedis-2.3.1.jar" /> |
| | | <classpathentry kind="lib" path="ext/commons-pool2-2.0.jar" sourcepath="ext/src/commons-pool2-2.0.jar" /> |
| | | <classpathentry kind="lib" path="ext/pf4j-0.6.jar" sourcepath="ext/src/pf4j-0.6.jar" /> |
| | | <classpathentry kind="lib" path="ext/junit-4.11.jar" sourcepath="ext/src/junit-4.11.jar" /> |
| | | <classpathentry kind="lib" path="ext/hamcrest-core-1.3.jar" sourcepath="ext/src/hamcrest-core-1.3.jar" /> |
| | | <classpathentry kind="lib" path="ext/selenium-java-2.28.0.jar" sourcepath="ext/src/selenium-java-2.28.0.jar" /> |
| | |
| | | - compile 'args4j:args4j:2.0.26' :war :fedclient :authority |
| | | - compile 'commons-codec:commons-codec:1.7' :war |
| | | - compile 'redis.clients:jedis:2.3.1' :war |
| | | - compile 'ro.fortsoft.pf4j:pf4j:0.6' :war |
| | | - test 'junit' |
| | | # Dependencies for Selenium web page testing |
| | | - test 'org.seleniumhq.selenium:selenium-java:${selenium.version}' @jar |
| | |
| | | </SOURCES> |
| | | </library> |
| | | </orderEntry> |
| | | <orderEntry type="module-library"> |
| | | <library name="pf4j-0.6.jar"> |
| | | <CLASSES> |
| | | <root url="jar://$MODULE_DIR$/ext/pf4j-0.6.jar!/" /> |
| | | </CLASSES> |
| | | <JAVADOC /> |
| | | <SOURCES> |
| | | <root url="jar://$MODULE_DIR$/ext/src/pf4j-0.6.jar!/" /> |
| | | </SOURCES> |
| | | </library> |
| | | </orderEntry> |
| | | <orderEntry type="module-library" scope="TEST"> |
| | | <library name="junit-4.11.jar"> |
| | | <CLASSES> |
| | |
| | | # SINCE 0.5.0
|
| | | # RESTART REQUIRED
|
| | | server.shutdownPort = 8081
|
| | |
|
| | | # Base folder for plugins.
|
| | | # This folder may contain Gitblit plugins
|
| | | #
|
| | | # SINCE 1.6.0
|
| | | # RESTART REQUIRED
|
| | | # BASEFOLDER
|
| | | plugins.folder = ${baseFolder}/plugins
|
| | |
| | | <url-pattern>/robots.txt</url-pattern>
|
| | | </servlet-mapping>
|
| | |
|
| | | |
| | | <!-- Git Access Restriction Filter
|
| | | <url-pattern> MUST match:
|
| | | * GitServlet
|
| | |
| | | |
| | | import com.gitblit.manager.AuthenticationManager; |
| | | import com.gitblit.manager.FederationManager; |
| | | import com.gitblit.manager.PluginManager; |
| | | import com.gitblit.manager.IAuthenticationManager; |
| | | import com.gitblit.manager.IFederationManager; |
| | | import com.gitblit.manager.IGitblit; |
| | | import com.gitblit.manager.IPluginManager; |
| | | import com.gitblit.manager.INotificationManager; |
| | | import com.gitblit.manager.IProjectManager; |
| | | import com.gitblit.manager.IRepositoryManager; |
| | |
| | | IRepositoryManager.class, |
| | | IProjectManager.class, |
| | | IFederationManager.class, |
| | | IPluginManager.class, |
| | | |
| | | // the monolithic manager |
| | | IGitblit.class, |
| | |
| | | |
| | | @Provides @Singleton IUserManager provideUserManager(IRuntimeManager runtimeManager) { |
| | | return new UserManager(runtimeManager); |
| | | } |
| | | |
| | | @Provides @Singleton IPluginManager providePluginManager(IRuntimeManager runtimeManager) { |
| | | return new PluginManager(runtimeManager); |
| | | } |
| | | |
| | | @Provides @Singleton IAuthenticationManager provideAuthenticationManager( |
| | |
| | | IPublicKeyManager publicKeyManager, |
| | | IRepositoryManager repositoryManager, |
| | | IProjectManager projectManager, |
| | | IFederationManager federationManager) { |
| | | IFederationManager federationManager, |
| | | IPluginManager pluginManager) { |
| | | |
| | | return new GitBlit( |
| | | runtimeManager, |
| | |
| | | publicKeyManager, |
| | | repositoryManager, |
| | | projectManager, |
| | | federationManager); |
| | | federationManager, |
| | | pluginManager); |
| | | } |
| | | |
| | | @Provides @Singleton GitBlitWebApp provideWebApplication( |
| | |
| | | UserManager users = new UserManager(runtime).start();
|
| | | RepositoryManager repositories = new RepositoryManager(runtime, users).start();
|
| | | FederationManager federation = new FederationManager(runtime, notifications, repositories).start();
|
| | | IGitblit gitblit = new GitblitManager(runtime, notifications, users, null, null, repositories, null, federation);
|
| | | IGitblit gitblit = new GitblitManager(runtime, notifications, users, null, null, repositories, null, federation, null);
|
| | |
|
| | | FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) {
|
| | | @Override
|
| | |
| | | import com.gitblit.manager.IFederationManager; |
| | | import com.gitblit.manager.IGitblit; |
| | | import com.gitblit.manager.INotificationManager; |
| | | import com.gitblit.manager.IPluginManager; |
| | | import com.gitblit.manager.IProjectManager; |
| | | import com.gitblit.manager.IRepositoryManager; |
| | | import com.gitblit.manager.IRuntimeManager; |
| | |
| | | IPublicKeyManager publicKeyManager, |
| | | IRepositoryManager repositoryManager, |
| | | IProjectManager projectManager, |
| | | IFederationManager federationManager) { |
| | | IFederationManager federationManager, |
| | | IPluginManager pluginManager) { |
| | | |
| | | super(runtimeManager, |
| | | notificationManager, |
| | |
| | | publicKeyManager, |
| | | repositoryManager, |
| | | projectManager, |
| | | federationManager); |
| | | federationManager, |
| | | pluginManager); |
| | | |
| | | this.injector = ObjectGraph.create(getModules()); |
| | | |
| | |
| | | inject(objectGraph);
|
| | | }
|
| | |
|
| | | protected abstract void inject(ObjectGraph dagger);
|
| | | protected abstract void inject(ObjectGraph dagger) throws ServletException;
|
| | |
|
| | | @Override
|
| | | public void destroy() {
|
| | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import ro.fortsoft.pf4j.PluginWrapper; |
| | | |
| | | import com.gitblit.Constants; |
| | | import com.gitblit.Constants.AccessPermission; |
| | | import com.gitblit.Constants.AccessRestrictionType; |
| | |
| | | |
| | | protected final IFederationManager federationManager; |
| | | |
| | | protected final IPluginManager pluginManager; |
| | | |
| | | public GitblitManager( |
| | | IRuntimeManager runtimeManager, |
| | | INotificationManager notificationManager, |
| | |
| | | IPublicKeyManager publicKeyManager, |
| | | IRepositoryManager repositoryManager, |
| | | IProjectManager projectManager, |
| | | IFederationManager federationManager) { |
| | | IFederationManager federationManager, |
| | | IPluginManager pluginManager) { |
| | | |
| | | this.settings = runtimeManager.getSettings(); |
| | | this.runtimeManager = runtimeManager; |
| | |
| | | this.repositoryManager = repositoryManager; |
| | | this.projectManager = projectManager; |
| | | this.federationManager = federationManager; |
| | | this.pluginManager = pluginManager; |
| | | } |
| | | |
| | | @Override |
| | |
| | | public boolean isIdle(Repository repository) { |
| | | return repositoryManager.isIdle(repository); |
| | | } |
| | | |
| | | @Override |
| | | public <T> List<T> getExtensions(Class<T> clazz) { |
| | | return pluginManager.getExtensions(clazz); |
| | | } |
| | | |
| | | @Override |
| | | public PluginWrapper whichPlugin(Class<?> clazz) { |
| | | return pluginManager.whichPlugin(clazz); |
| | | } |
| | | } |
| | |
| | | IAuthenticationManager, |
| | | IRepositoryManager, |
| | | IProjectManager, |
| | | IFederationManager { |
| | | IFederationManager, |
| | | IPluginManager { |
| | | |
| | | /** |
| | | * Returns a list of repository URLs and the user access permission. |
New file |
| | |
| | | /* |
| | | * Copyright 2014 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.manager; |
| | | |
| | | import java.util.List; |
| | | |
| | | import ro.fortsoft.pf4j.PluginWrapper; |
| | | |
| | | public interface IPluginManager extends IManager { |
| | | |
| | | /** |
| | | * Retrieves the extension for given class 'clazz'. |
| | | * |
| | | * @param clazz extension point class to retrieve extension for |
| | | * @return list of extensions |
| | | */ |
| | | public <T> List<T> getExtensions(Class<T> clazz); |
| | | |
| | | /** |
| | | * Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'. |
| | | * |
| | | * @param clazz extension point class to retrieve extension for |
| | | * @return PluginWrapper that loaded the given class |
| | | */ |
| | | public PluginWrapper whichPlugin(Class<?> clazz); |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright 2014 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.manager; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import ro.fortsoft.pf4j.DefaultPluginManager; |
| | | |
| | | import com.gitblit.Keys; |
| | | |
| | | /** |
| | | * The plugin manager maintains the lifecycle of plugins. It is exposed as |
| | | * Dagger bean. The extension consumers supposed to retrieve plugin manager |
| | | * from the Dagger DI and retrieve extensions provided by active plugins. |
| | | * |
| | | * @author David Ostrovsky |
| | | * |
| | | */ |
| | | public class PluginManager extends DefaultPluginManager implements |
| | | IPluginManager { |
| | | |
| | | private final Logger logger = LoggerFactory.getLogger(getClass()); |
| | | |
| | | public PluginManager(IRuntimeManager runtimeManager) { |
| | | super(runtimeManager.getFileOrFolder(Keys.plugins.folder, |
| | | "${baseFolder}/plugins")); |
| | | } |
| | | |
| | | @Override |
| | | public PluginManager start() { |
| | | logger.info("Plugin manager started"); |
| | | loadPlugins(); |
| | | startPlugins(); |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | public PluginManager stop() { |
| | | stopPlugins(); |
| | | return null; |
| | | } |
| | | } |
| | |
| | | import com.gitblit.manager.IAuthenticationManager; |
| | | import com.gitblit.manager.IFederationManager; |
| | | import com.gitblit.manager.IGitblit; |
| | | import com.gitblit.manager.IPluginManager; |
| | | import com.gitblit.manager.IManager; |
| | | import com.gitblit.manager.INotificationManager; |
| | | import com.gitblit.manager.IProjectManager; |
| | |
| | | startManager(injector, IProjectManager.class); |
| | | startManager(injector, IFederationManager.class); |
| | | startManager(injector, IGitblit.class); |
| | | startManager(injector, IPluginManager.class); |
| | | |
| | | logger.info(""); |
| | | logger.info("All managers started."); |
| | |
| | | import java.text.MessageFormat;
|
| | |
|
| | | import javax.servlet.FilterChain;
|
| | | import javax.servlet.FilterConfig;
|
| | | import javax.servlet.ServletException;
|
| | | import javax.servlet.ServletRequest;
|
| | | import javax.servlet.ServletResponse;
|