James Moger
2014-07-03 a40cbcfc4fab2ca16304c7393a68fe95a9322edc
Merged #80 "Replace Dagger with Guice"
6 files added
63 files modified
5 files deleted
3496 ■■■■ changed files
.classpath 8 ●●●● patch | view | raw | blame | history
NOTICE 9 ●●●●● patch | view | raw | blame | history
build.moxie 33 ●●●● patch | view | raw | blame | history
build.xml 10 ●●●●● patch | view | raw | blame | history
gitblit.iml 40 ●●●● patch | view | raw | blame | history
releases.moxie 1 ●●●● patch | view | raw | blame | history
src/main/java/WEB-INF/web.xml 408 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/Constants.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/DaggerModule.java 215 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/FederationClient.java 378 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/GitBlit.java 444 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/dagger/DaggerContext.java 67 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/dagger/DaggerFilter.java 47 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/dagger/DaggerServlet.java 44 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/dagger/DaggerWicketFilter.java 45 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/guice/CoreModule.java 79 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/guice/IPublicKeyManagerProvider.java 72 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/guice/ITicketServiceProvider.java 73 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/guice/WebModule.java 105 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/guice/WorkQueueProvider.java 57 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/AuthenticationManager.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/FederationManager.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/GitblitManager.java 163 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/IGitblit.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/IRuntimeManager.java 39 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/IServicesManager.java 75 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/NotificationManager.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/PluginManager.java 57 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/ProjectManager.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/RepositoryManager.java 34 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/RuntimeManager.java 59 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/ServicesManager.java 226 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/UserManager.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/AuthenticationFilter.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/BranchGraphServlet.java 25 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/DownloadZipFilter.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/DownloadZipServlet.java 17 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/EnforceAuthenticationFilter.java 34 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/FederationServlet.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/GitFilter.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/GitServlet.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/GitblitContext.java 71 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/JsonServlet.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/LogoServlet.java 15 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/PagesFilter.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/PagesServlet.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/ProxyFilter.java 33 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/PtServlet.java 15 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/RawFilter.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/RawServlet.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/RobotsTxtServlet.java 15 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/RpcFilter.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/RpcServlet.java 13 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/SyndicationFilter.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/SyndicationServlet.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/tickets/BranchTicketService.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/tickets/FileTicketService.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/tickets/ITicketService.java 5 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/tickets/NullTicketService.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/tickets/RedisTicketService.java 8 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/FileKeyManager.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/NullKeyManager.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/GitBlitWebApp.java 36 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/GitblitWicketApp.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/GitblitWicketFilter.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/TicketPage.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/UserPage.java 8 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java 4 ●●●● patch | view | raw | blame | history
src/site/design.mkd 1 ●●●● patch | view | raw | blame | history
src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java 26 ●●●● patch | view | raw | blame | history
.classpath
@@ -5,10 +5,11 @@
    <classpathentry kind="src" path="src/test/java" output="bin/test-classes" />
    <classpathentry kind="src" path="src/test/bugtraq" output="bin/test-classes" />
    <classpathentry kind="src" path="src/main/resources" />
    <classpathentry kind="lib" path="ext/dagger-1.1.0.jar" sourcepath="ext/src/dagger-1.1.0.jar" />
    <classpathentry kind="lib" path="ext/guice-4.0-beta4.jar" sourcepath="ext/src/guice-4.0-beta4.jar" />
    <classpathentry kind="lib" path="ext/javax.inject-1.jar" sourcepath="ext/src/javax.inject-1.jar" />
    <classpathentry kind="lib" path="ext/dagger-compiler-1.1.0.jar" sourcepath="ext/src/dagger-compiler-1.1.0.jar" />
    <classpathentry kind="lib" path="ext/javawriter-2.1.1.jar" sourcepath="ext/src/javawriter-2.1.1.jar" />
    <classpathentry kind="lib" path="ext/aopalliance-1.0.jar" sourcepath="ext/src/aopalliance-1.0.jar" />
    <classpathentry kind="lib" path="ext/guava-17.0.jar" sourcepath="ext/src/guava-17.0.jar" />
    <classpathentry kind="lib" path="ext/guice-servlet-4.0-gb1.jar" sourcepath="ext/src/guice-servlet-4.0-gb1.jar" />
    <classpathentry kind="lib" path="ext/annotations-12.0.jar" sourcepath="ext/src/annotations-12.0.jar" />
    <classpathentry kind="lib" path="ext/log4j-1.2.17.jar" sourcepath="ext/src/log4j-1.2.17.jar" />
    <classpathentry kind="lib" path="ext/slf4j-api-1.7.7.jar" sourcepath="ext/src/slf4j-api-1.7.7.jar" />
@@ -70,7 +71,6 @@
    <classpathentry kind="lib" path="ext/waffle-jna-1.5.jar" sourcepath="ext/src/waffle-jna-1.5.jar" />
    <classpathentry kind="lib" path="ext/platform-3.5.0.jar" sourcepath="ext/src/platform-3.5.0.jar" />
    <classpathentry kind="lib" path="ext/jna-3.5.0.jar" sourcepath="ext/src/jna-3.5.0.jar" />
    <classpathentry kind="lib" path="ext/guava-13.0.1.jar" sourcepath="ext/src/guava-13.0.1.jar" />
    <classpathentry kind="lib" path="ext/libpam4j-1.7.jar" sourcepath="ext/src/libpam4j-1.7.jar" />
    <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" />
NOTICE
@@ -358,3 +358,12 @@
   Apache License 2.0
   https://github.com/decebals/pf4j
---------------------------------------------------------------------------
google-guice
---------------------------------------------------------------------------
   google-guice, release under the
   Apache License 2.0
   https://code.google.com/p/google-guice
build.moxie
@@ -96,9 +96,10 @@
- { id: eclipse, url: 'http://repo.eclipse.org/content/groups/releases' }
- { id: eclipse-snapshots, url: 'http://repo.eclipse.org/content/groups/snapshots' }
- { id: atlassian-contrib, url: 'https://maven.atlassian.com/content/repositories/atlassian-3rdparty' }
- { id: gitblit, url: 'http://gitblit.github.io/gitblit-maven' }
# Source all dependencies from the following repositories in the specified order
repositories: central, eclipse-snapshots, eclipse, atlassian-contrib
repositories: central, eclipse-snapshots, eclipse, atlassian-contrib, gitblit
# Convenience properties for dependencies
properties: {
@@ -112,6 +113,9 @@
  wikitext.version : 1.4
  sshd.version: 0.11.1-atlassian-1
  mina.version: 2.0.7
  guice.version : 4.0-beta4
  # Gitblit maintains a fork of guice-servlet
  guice-servlet.version : 4.0-gb1
  }
# Dependencies
@@ -126,15 +130,14 @@
#
dependencies:
# Dagger dependency injection library (annotation processor)
- compile 'com.squareup.dagger:dagger:1.1.0' :war apt
- compile 'com.squareup.dagger:dagger-compiler:1.1.0' :war optional apt
# Standard dependencies
- compile 'com.google.inject:guice:${guice.version}' :war :fedclient
- compile 'com.google.inject.extensions:guice-servlet:${guice-servlet.version}' :war
- compile 'com.google.guava:guava:17.0' :war :fedclient
- compile 'com.intellij:annotations:12.0' :war
- compile 'log4j:log4j:1.2.17' :war :fedclient :authority
- compile 'org.slf4j:slf4j-api:1.7.7' :war :fedclient :authority
- compile 'org.slf4j:slf4j-log4j12:1.7.7' :war :fedclient :authority
- compile 'com.sun.mail:javax.mail:1.5.1' :war :authority
- compile 'log4j:log4j:1.2.17' :war :fedclient
- compile 'org.slf4j:slf4j-api:1.7.7' :war :fedclient
- compile 'org.slf4j:slf4j-log4j12:1.7.7' :war :fedclient
- compile 'com.sun.mail:javax.mail:1.5.1' :war
- compile 'javax.servlet:javax.servlet-api:3.1.0' :fedclient
- compile 'org.eclipse.jetty.aggregate:jetty-all:${jetty.version}' @jar
- compile 'org.apache.wicket:wicket:${wicket.version}' :war !org.mockito
@@ -152,11 +155,11 @@
- compile 'org.fusesource.wikitext:tracwiki-core:${wikitext.version}' :war
- compile 'org.fusesource.wikitext:mediawiki-core:${wikitext.version}' :war
- compile 'org.fusesource.wikitext:confluence-core:${wikitext.version}' :war
- compile 'org.eclipse.jgit:org.eclipse.jgit:${jgit.version}' :war :fedclient :manager :authority !junit
- compile 'org.eclipse.jgit:org.eclipse.jgit.http.server:${jgit.version}' :war :manager :authority !junit
- compile 'org.bouncycastle:bcprov-jdk15on:${bouncycastle.version}' :war :authority
- compile 'org.bouncycastle:bcmail-jdk15on:${bouncycastle.version}' :war :authority
- compile 'org.bouncycastle:bcpkix-jdk15on:${bouncycastle.version}' :war :authority
- compile 'org.eclipse.jgit:org.eclipse.jgit:${jgit.version}' :war :fedclient :manager !junit
- compile 'org.eclipse.jgit:org.eclipse.jgit.http.server:${jgit.version}' :war :manager !junit
- compile 'org.bouncycastle:bcprov-jdk15on:${bouncycastle.version}' :war
- compile 'org.bouncycastle:bcmail-jdk15on:${bouncycastle.version}' :war
- compile 'org.bouncycastle:bcpkix-jdk15on:${bouncycastle.version}' :war
- compile 'org.apache.sshd:sshd-core:${sshd.version}' :war !org.easymock
- compile 'org.apache.mina:mina-core:${mina.version}' :war !org.easymock
- compile 'rome:rome:0.9' :war :manager :api
@@ -171,7 +174,7 @@
- compile 'org.freemarker:freemarker:2.3.20' :war
- compile 'com.github.dblock.waffle:waffle-jna:1.5' :war
- compile 'org.kohsuke:libpam4j:1.7' :war
- compile 'args4j:args4j:2.0.26' :war :fedclient :authority
- compile 'args4j:args4j:2.0.26' :war :fedclient
- compile 'commons-codec:commons-codec:1.7' :war
- compile 'redis.clients:jedis:2.3.1' :war
- compile 'ro.fortsoft.pf4j:pf4j:0.8.0' :war
build.xml
@@ -295,7 +295,7 @@
             classes, exclude any classes in classpath jars -->
        <mx:genjar tag="" includeresources="false" excludeClasspathJars="true"
            destfile="${project.targetDirectory}/fedclient.jar"
            excludes="**/.class,**/*.java, **/Thumbs.db, **/*.mkd, com/gitblit/wicket/**">
            excludes="**/.class, **/*.java, **/Thumbs.db, **/*.mkd, **/*.md, **/*.css, com/gitblit/wicket/**">
            <mainclass name="com.gitblit.FederationClient" />
            <class name="com.gitblit.Keys" />
            <launcher paths="ext" />
@@ -335,7 +335,8 @@
        <!-- generate jar by traversing the class hierarchy of the specified
             classes, exclude any classes in classpath jars -->
        <mx:genjar tag="" includeResources="false" excludeClasspathJars="true"
            destfile="${project.targetDirectory}/manager.jar">
            destfile="${project.targetDirectory}/manager.jar"
            excludes="**/.class, **/*.java, **/Thumbs.db, **/*.mkd, **/*.md, **/*.css, com/gitblit/wicket/**">
            <resource file="${project.src.dir}/com/gitblit/client/splash.png" />
            <resource file="${project.resources.dir}/gitblt-favicon.png" />
            <resource file="${project.resources.dir}/gitweb-favicon.png" />
@@ -411,9 +412,10 @@
        <!-- Build API Library jar -->
        <mx:genjar tag="" includeResources="false" excludeClasspathJars="true"
            destfile="${project.targetDirectory}/gbapi-${project.version}.jar">
            destfile="${project.targetDirectory}/gbapi-${project.version}.jar"
            excludes="**/.class, **/*.java, **/Thumbs.db, **/*.mkd, **/*.md, **/*.css, com/gitblit/wicket/**">
            <mainclass name="com.gitblit.client.GitblitClient" />
            <class name="com.gitblit.Keys" />
            <class name="com.gitblit.client.GitblitClient" />
            <class name="com.gitblit.models.FederationModel" />
            <class name="com.gitblit.models.FederationProposal" />
            <class name="com.gitblit.models.FederationSet" />            
gitblit.iml
@@ -14,13 +14,13 @@
    </content>
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="module-library">
      <library name="dagger-1.1.0.jar">
      <library name="guice-4.0-beta4.jar">
        <CLASSES>
          <root url="jar://$MODULE_DIR$/ext/dagger-1.1.0.jar!/" />
          <root url="jar://$MODULE_DIR$/ext/guice-4.0-beta4.jar!/" />
        </CLASSES>
        <JAVADOC />
        <SOURCES>
          <root url="jar://$MODULE_DIR$/ext/src/dagger-1.1.0.jar!/" />
          <root url="jar://$MODULE_DIR$/ext/src/guice-4.0-beta4.jar!/" />
        </SOURCES>
      </library>
    </orderEntry>
@@ -36,24 +36,35 @@
      </library>
    </orderEntry>
    <orderEntry type="module-library">
      <library name="dagger-compiler-1.1.0.jar">
      <library name="aopalliance-1.0.jar">
        <CLASSES>
          <root url="jar://$MODULE_DIR$/ext/dagger-compiler-1.1.0.jar!/" />
          <root url="jar://$MODULE_DIR$/ext/aopalliance-1.0.jar!/" />
        </CLASSES>
        <JAVADOC />
        <SOURCES>
          <root url="jar://$MODULE_DIR$/ext/src/dagger-compiler-1.1.0.jar!/" />
          <root url="jar://$MODULE_DIR$/ext/src/aopalliance-1.0.jar!/" />
        </SOURCES>
      </library>
    </orderEntry>
    <orderEntry type="module-library">
      <library name="javawriter-2.1.1.jar">
      <library name="guava-17.0.jar">
        <CLASSES>
          <root url="jar://$MODULE_DIR$/ext/javawriter-2.1.1.jar!/" />
          <root url="jar://$MODULE_DIR$/ext/guava-17.0.jar!/" />
        </CLASSES>
        <JAVADOC />
        <SOURCES>
          <root url="jar://$MODULE_DIR$/ext/src/javawriter-2.1.1.jar!/" />
          <root url="jar://$MODULE_DIR$/ext/src/guava-17.0.jar!/" />
        </SOURCES>
      </library>
    </orderEntry>
    <orderEntry type="module-library">
      <library name="guice-servlet-4.0-gb1.jar">
        <CLASSES>
          <root url="jar://$MODULE_DIR$/ext/guice-servlet-4.0-gb1.jar!/" />
        </CLASSES>
        <JAVADOC />
        <SOURCES>
          <root url="jar://$MODULE_DIR$/ext/src/guice-servlet-4.0-gb1.jar!/" />
        </SOURCES>
      </library>
    </orderEntry>
@@ -721,17 +732,6 @@
        <JAVADOC />
        <SOURCES>
          <root url="jar://$MODULE_DIR$/ext/src/jna-3.5.0.jar!/" />
        </SOURCES>
      </library>
    </orderEntry>
    <orderEntry type="module-library">
      <library name="guava-13.0.1.jar">
        <CLASSES>
          <root url="jar://$MODULE_DIR$/ext/guava-13.0.1.jar!/" />
        </CLASSES>
        <JAVADOC />
        <SOURCES>
          <root url="jar://$MODULE_DIR$/ext/src/guava-13.0.1.jar!/" />
        </SOURCES>
      </library>
    </orderEntry>
releases.moxie
@@ -24,6 +24,7 @@
    - Jetty 9.2.1 (pr-202)
    - Lucene 4.8.1 (pr-201)
    - JGit 3.4.0 (pr-200)
    - Guice 4.0-beta4 (ticket-80)
    - SLF4j 1.7.7 (ticket-122)
    - gson 2.2.2 (ticket-123)
    - Freemarker 2.3.20 (ticket-124)
src/main/java/WEB-INF/web.xml
@@ -1,361 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <!-- The base folder is used to specify the root location of your Gitblit data.
            ${baseFolder}/gitblit.properties
            ${baseFolder}/users.conf
            ${baseFolder}/projects.conf
            ${baseFolder}/robots.txt
            ${baseFolder}/git
            ${baseFolder}/groovy
            ${baseFolder}/groovy/grape
            ${baseFolder}/proposals
        By default, this location is WEB-INF/data.  It is recommended to set this
        path to a location outside your webapps folder that is writable by your
        servlet container.  Gitblit will copy the WEB-INF/data files to that
        location for you when it restarts.  This approach makes upgrading simpler.
        All you have to do is set this parameter for the new release and then
        review the defaults for any new settings.  Settings are always versioned
        with a SINCE x.y.z attribute and also noted in the release changelog.
        -->
    <env-entry>
        <description>The base folder is used to specify the root location of your Gitblit data.</description>
        <env-entry-name>baseFolder</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
        <env-entry-value>${contextFolder}/WEB-INF/data</env-entry-value>
    </env-entry>
    <!-- Gitblit Displayname -->
    <display-name>Gitblit - @gb.version@</display-name>
<!-- Gitblit Context Listener --><!-- STRIP
    <listener>
         <listener-class>com.gitblit.servlet.GitblitContext</listener-class>
     </listener>STRIP -->
    <!-- Git Servlet
         <url-pattern> MUST match:
            * GitFilter
            * com.gitblit.Constants.GIT_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>GitServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.GitServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GitServlet</servlet-name>
        <url-pattern>/git/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>GitServlet</servlet-name>
        <url-pattern>/r/*</url-pattern>
    </servlet-mapping>
    <!-- SparkleShare Invite Servlet
         <url-pattern> MUST match:
            * com.gitblit.Constants.SPARKLESHARE_INVITE_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>SparkleShareInviteServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.SparkleShareInviteServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SparkleShareInviteServlet</servlet-name>
        <url-pattern>/sparkleshare/*</url-pattern>
    </servlet-mapping>
    <!-- Syndication Servlet
         <url-pattern> MUST match:
            * SyndicationFilter
            * com.gitblit.Constants.SYNDICATION_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>SyndicationServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.SyndicationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SyndicationServlet</servlet-name>
        <url-pattern>/feed/*</url-pattern>
    </servlet-mapping>
    <!-- Zip Servlet
         <url-pattern> MUST match:
            * ZipServlet
            * com.gitblit.Constants.ZIP_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>ZipServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.DownloadZipServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ZipServlet</servlet-name>
        <url-pattern>/zip/*</url-pattern>
    </servlet-mapping>
    <!-- Federation Servlet
         <url-pattern> MUST match:
             * com.gitblit.Constants.FEDERATION_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>FederationServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.FederationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FederationServlet</servlet-name>
        <url-pattern>/federation/*</url-pattern>
    </servlet-mapping>
    <!-- Rpc Servlet
         <url-pattern> MUST match:
             * com.gitblit.Constants.RPC_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>RpcServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.RpcServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RpcServlet</servlet-name>
        <url-pattern>/rpc/*</url-pattern>
    </servlet-mapping>
    <!-- Raw Servlet
         <url-pattern> MUST match:
            * RawFilter
            * com.gitblit.Constants.RAW_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>RawServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.RawServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RawServlet</servlet-name>
        <url-pattern>/raw/*</url-pattern>
    </servlet-mapping>
    <!-- Pages Servlet
         <url-pattern> MUST match:
            * PagesFilter
            * com.gitblit.Constants.PAGES_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>PagesServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.PagesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PagesServlet</servlet-name>
        <url-pattern>/pages/*</url-pattern>
    </servlet-mapping>
    <!-- Logo Servlet
         <url-pattern> MUST match:
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>LogoServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.LogoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoServlet</servlet-name>
        <url-pattern>/logo.png</url-pattern>
    </servlet-mapping>
    <!-- PT Servlet
         <url-pattern> MUST match:
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>PtServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.PtServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PtServlet</servlet-name>
        <url-pattern>/pt</url-pattern>
    </servlet-mapping>
    <!-- Branch Graph Servlet
         <url-pattern> MUST match:
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>BranchGraphServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.BranchGraphServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>BranchGraphServlet</servlet-name>
        <url-pattern>/graph/*</url-pattern>
    </servlet-mapping>
    <!-- Robots.txt Servlet
         <url-pattern> MUST match:
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>RobotsTxtServlet</servlet-name>
        <servlet-class>com.gitblit.servlet.RobotsTxtServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RobotsTxtServlet</servlet-name>
        <url-pattern>/robots.txt</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>ProxyFilter</filter-name>
        <filter-class>com.gitblit.servlet.ProxyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ProxyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Git Access Restriction Filter
         <url-pattern> MUST match:
            * GitServlet
            * com.gitblit.Constants.GIT_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>GitFilter</filter-name>
        <filter-class>com.gitblit.servlet.GitFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>GitFilter</filter-name>
        <url-pattern>/git/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>GitFilter</filter-name>
        <url-pattern>/r/*</url-pattern>
    </filter-mapping>
    <!-- Syndication Restriction Filter
         <url-pattern> MUST match:
            * SyndicationServlet
            * com.gitblit.Constants.SYNDICATION_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>SyndicationFilter</filter-name>
        <filter-class>com.gitblit.servlet.SyndicationFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SyndicationFilter</filter-name>
        <url-pattern>/feed/*</url-pattern>
    </filter-mapping>
    <!-- Download Zip Restriction Filter
         <url-pattern> MUST match:
            * DownloadZipServlet
            * com.gitblit.Constants.ZIP_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>ZipFilter</filter-name>
        <filter-class>com.gitblit.servlet.DownloadZipFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ZipFilter</filter-name>
        <url-pattern>/zip/*</url-pattern>
    </filter-mapping>
    <!-- Rpc Restriction Filter
         <url-pattern> MUST match:
            * RpcServlet
            * com.gitblit.Constants.RPC_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>RpcFilter</filter-name>
        <filter-class>com.gitblit.servlet.RpcFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RpcFilter</filter-name>
        <url-pattern>/rpc/*</url-pattern>
    </filter-mapping>
    <!-- Branch Restriction Filter
         <url-pattern> MUST match:
            * RawServlet
            * com.gitblit.Constants.BRANCH_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>RawFilter</filter-name>
        <filter-class>com.gitblit.servlet.RawFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RawFilter</filter-name>
        <url-pattern>/raw/*</url-pattern>
    </filter-mapping>
    <!-- Pages Restriction Filter
         <url-pattern> MUST match:
            * PagesServlet
            * com.gitblit.Constants.PAGES_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>PagesFilter</filter-name>
        <filter-class>com.gitblit.servlet.PagesFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PagesFilter</filter-name>
        <url-pattern>/pages/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>EnforceAuthenticationFilter</filter-name>
        <filter-class>com.gitblit.servlet.EnforceAuthenticationFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>EnforceAuthenticationFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Wicket Filter -->
    <filter>
        <filter-name>wicketFilter</filter-name>
        <filter-class>
            com.gitblit.wicket.GitblitWicketFilter
        </filter-class>
        <init-param>
            <param-name>ignorePaths</param-name>
            <!-- Paths should match
                 * SyndicationFilter <url-pattern>
                 * SyndicationServlet <url-pattern>
                 * com.gitblit.Constants.SYNDICATION_PATH
                 * GitFilter <url-pattern>
                 * GitServlet <url-pattern>
                 * com.gitblit.Constants.GIT_PATH
                 * SparkleshareInviteServlet <url-pattern>
                 * com.gitblit.Constants.SPARKLESHARE_INVITE_PATH
                 * Zipfilter <url-pattern>
                 * ZipServlet <url-pattern>
                 * com.gitblit.Constants.ZIP_PATH
                 * FederationServlet <url-pattern>
                 * RpcFilter <url-pattern>
                 * RpcServlet <url-pattern>
                 * RawFilter <url-pattern>
                 * RawServlet <url-pattern>
                 * PagesFilter <url-pattern>
                 * PagesServlet <url-pattern>
                 * com.gitblit.Constants.PAGES_PATH -->
            <param-value>r/,git/,pt,feed/,zip/,federation/,rpc/,raw/,pages/,robots.txt,logo.png,graph/,sparkleshare/</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>wicketFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <!-- The base folder is used to specify the root location of your Gitblit data.
            ${baseFolder}/gitblit.properties
            ${baseFolder}/users.conf
            ${baseFolder}/projects.conf
            ${baseFolder}/robots.txt
            ${baseFolder}/git
            ${baseFolder}/groovy
            ${baseFolder}/groovy/grape
            ${baseFolder}/proposals
        By default, this location is WEB-INF/data.  It is recommended to set this
        path to a location outside your webapps folder that is writable by your
        servlet container.  Gitblit will copy the WEB-INF/data files to that
        location for you when it restarts.  This approach makes upgrading simpler.
        All you have to do is set this parameter for the new release and then
        review the defaults for any new settings.  Settings are always versioned
        with a SINCE x.y.z attribute and also noted in the release changelog.
        -->
    <env-entry>
        <description>The base folder is used to specify the root location of your Gitblit data.</description>
        <env-entry-name>baseFolder</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
        <env-entry-value>${contextFolder}/WEB-INF/data</env-entry-value>
    </env-entry>
    <!-- Gitblit Displayname -->
    <display-name>Gitblit - @gb.version@</display-name>
    <listener>
          <listener-class>com.gitblit.servlet.GitblitContext</listener-class>
    </listener>
    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
src/main/java/com/gitblit/Constants.java
@@ -70,6 +70,8 @@
    public static final String RAW_PATH = "/raw/";
    public static final String PT_PATH = "/pt";
    public static final String BRANCH_GRAPH_PATH = "/graph/";
    public static final String BORDER = "*****************************************************************";
src/main/java/com/gitblit/DaggerModule.java
File was deleted
src/main/java/com/gitblit/FederationClient.java
@@ -1,189 +1,189 @@
/*
 * Copyright 2011 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;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import com.gitblit.manager.FederationManager;
import com.gitblit.manager.GitblitManager;
import com.gitblit.manager.IGitblit;
import com.gitblit.manager.INotificationManager;
import com.gitblit.manager.RepositoryManager;
import com.gitblit.manager.RuntimeManager;
import com.gitblit.manager.UserManager;
import com.gitblit.models.FederationModel;
import com.gitblit.models.Mailing;
import com.gitblit.service.FederationPullService;
import com.gitblit.utils.FederationUtils;
import com.gitblit.utils.StringUtils;
/**
 * Command-line client to pull federated Gitblit repositories.
 *
 * @author James Moger
 *
 */
public class FederationClient {
    public static void main(String[] args) {
        Params params = new Params();
        CmdLineParser parser = new CmdLineParser(params);
        try {
            parser.parseArgument(args);
        } catch (CmdLineException t) {
            usage(parser, t);
        }
        System.out.println("Gitblit Federation Client v" + Constants.getVersion() + " (" + Constants.getBuildDate() + ")");
        // command-line specified base folder
        File baseFolder = new File(System.getProperty("user.dir"));
        if (!StringUtils.isEmpty(params.baseFolder)) {
            baseFolder = new File(params.baseFolder);
        }
        File regFile = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.registrationsFile);
        FileSettings settings = new FileSettings(regFile.getAbsolutePath());
        List<FederationModel> registrations = new ArrayList<FederationModel>();
        if (StringUtils.isEmpty(params.url)) {
            registrations.addAll(FederationUtils.getFederationRegistrations(settings));
        } else {
            if (StringUtils.isEmpty(params.token)) {
                System.out.println("Must specify --token parameter!");
                System.exit(0);
            }
            FederationModel model = new FederationModel("Gitblit");
            model.url = params.url;
            model.token = params.token;
            model.mirror = params.mirror;
            model.bare = params.bare;
            model.folder = "";
            registrations.add(model);
        }
        if (registrations.size() == 0) {
            System.out.println("No Federation Registrations!  Nothing to do.");
            System.exit(0);
        }
        // command-line specified repositories folder
        if (!StringUtils.isEmpty(params.repositoriesFolder)) {
            settings.overrideSetting(Keys.git.repositoriesFolder, new File(
                    params.repositoriesFolder).getAbsolutePath());
        }
        // configure the Gitblit singleton for minimal, non-server operation
        RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start();
        NoopNotificationManager notifications = new NoopNotificationManager().start();
        UserManager users = new UserManager(runtime, null).start();
        RepositoryManager repositories = new RepositoryManager(runtime, null, users).start();
        FederationManager federation = new FederationManager(runtime, notifications, repositories).start();
        IGitblit gitblit = new GitblitManager(runtime, null, notifications, users, null, null, repositories, null, federation);
        FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) {
            @Override
            public void reschedule(FederationModel registration) {
                // NOOP
            }
        };
        puller.run();
        System.out.println("Finished.");
        System.exit(0);
    }
    private static void usage(CmdLineParser parser, CmdLineException t) {
        System.out.println(Constants.getGitBlitVersion());
        System.out.println();
        if (t != null) {
            System.out.println(t.getMessage());
            System.out.println();
        }
        if (parser != null) {
            parser.printUsage(System.out);
        }
        System.exit(0);
    }
    /**
     * Parameters class for FederationClient.
     */
    private static class Params {
        @Option(name = "--registrations", usage = "Gitblit Federation Registrations File", metaVar = "FILE")
        public String registrationsFile = "${baseFolder}/federation.properties";
        @Option(name = "--url", usage = "URL of Gitblit instance to mirror from", metaVar = "URL")
        public String url;
        @Option(name = "--mirror", usage = "Mirror repositories")
        public boolean mirror;
        @Option(name = "--bare", usage = "Create bare repositories")
        public boolean bare;
        @Option(name = "--token", usage = "Federation Token", metaVar = "TOKEN")
        public String token;
        @Option(name = "--baseFolder", usage = "Base folder for received data", metaVar = "PATH")
        public String baseFolder;
        @Option(name = "--repositoriesFolder", usage = "Destination folder for cloned repositories", metaVar = "PATH")
        public String repositoriesFolder;
    }
    private static class NoopNotificationManager implements INotificationManager {
        @Override
        public NoopNotificationManager start() {
            return this;
        }
        @Override
        public NoopNotificationManager stop() {
            return this;
        }
        @Override
        public boolean isSendingMail() {
            return false;
        }
        @Override
        public void sendMailToAdministrators(String subject, String message) {
        }
        @Override
        public void sendMail(String subject, String message, Collection<String> toAddresses) {
        }
        @Override
        public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
        }
        @Override
        public void send(Mailing mailing) {
        }
    }
}
/*
 * Copyright 2011 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;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import com.gitblit.manager.FederationManager;
import com.gitblit.manager.GitblitManager;
import com.gitblit.manager.IGitblit;
import com.gitblit.manager.INotificationManager;
import com.gitblit.manager.RepositoryManager;
import com.gitblit.manager.RuntimeManager;
import com.gitblit.manager.UserManager;
import com.gitblit.models.FederationModel;
import com.gitblit.models.Mailing;
import com.gitblit.service.FederationPullService;
import com.gitblit.utils.FederationUtils;
import com.gitblit.utils.StringUtils;
/**
 * Command-line client to pull federated Gitblit repositories.
 *
 * @author James Moger
 *
 */
public class FederationClient {
    public static void main(String[] args) {
        Params params = new Params();
        CmdLineParser parser = new CmdLineParser(params);
        try {
            parser.parseArgument(args);
        } catch (CmdLineException t) {
            usage(parser, t);
        }
        System.out.println("Gitblit Federation Client v" + Constants.getVersion() + " (" + Constants.getBuildDate() + ")");
        // command-line specified base folder
        File baseFolder = new File(System.getProperty("user.dir"));
        if (!StringUtils.isEmpty(params.baseFolder)) {
            baseFolder = new File(params.baseFolder);
        }
        File regFile = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.registrationsFile);
        FileSettings settings = new FileSettings(regFile.getAbsolutePath());
        List<FederationModel> registrations = new ArrayList<FederationModel>();
        if (StringUtils.isEmpty(params.url)) {
            registrations.addAll(FederationUtils.getFederationRegistrations(settings));
        } else {
            if (StringUtils.isEmpty(params.token)) {
                System.out.println("Must specify --token parameter!");
                System.exit(0);
            }
            FederationModel model = new FederationModel("Gitblit");
            model.url = params.url;
            model.token = params.token;
            model.mirror = params.mirror;
            model.bare = params.bare;
            model.folder = "";
            registrations.add(model);
        }
        if (registrations.size() == 0) {
            System.out.println("No Federation Registrations!  Nothing to do.");
            System.exit(0);
        }
        // command-line specified repositories folder
        if (!StringUtils.isEmpty(params.repositoriesFolder)) {
            settings.overrideSetting(Keys.git.repositoriesFolder, new File(
                    params.repositoriesFolder).getAbsolutePath());
        }
        // configure the Gitblit singleton for minimal, non-server operation
        RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start();
        NoopNotificationManager notifications = new NoopNotificationManager().start();
        UserManager users = new UserManager(runtime, null).start();
        RepositoryManager repositories = new RepositoryManager(runtime, null, users).start();
        FederationManager federation = new FederationManager(runtime, notifications, repositories).start();
        IGitblit gitblit = new GitblitManager(null, null, runtime, null, notifications, users, null, repositories, null, federation);
        FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) {
            @Override
            public void reschedule(FederationModel registration) {
                // NOOP
            }
        };
        puller.run();
        System.out.println("Finished.");
        System.exit(0);
    }
    private static void usage(CmdLineParser parser, CmdLineException t) {
        System.out.println(Constants.getGitBlitVersion());
        System.out.println();
        if (t != null) {
            System.out.println(t.getMessage());
            System.out.println();
        }
        if (parser != null) {
            parser.printUsage(System.out);
        }
        System.exit(0);
    }
    /**
     * Parameters class for FederationClient.
     */
    private static class Params {
        @Option(name = "--registrations", usage = "Gitblit Federation Registrations File", metaVar = "FILE")
        public String registrationsFile = "${baseFolder}/federation.properties";
        @Option(name = "--url", usage = "URL of Gitblit instance to mirror from", metaVar = "URL")
        public String url;
        @Option(name = "--mirror", usage = "Mirror repositories")
        public boolean mirror;
        @Option(name = "--bare", usage = "Create bare repositories")
        public boolean bare;
        @Option(name = "--token", usage = "Federation Token", metaVar = "TOKEN")
        public String token;
        @Option(name = "--baseFolder", usage = "Base folder for received data", metaVar = "PATH")
        public String baseFolder;
        @Option(name = "--repositoriesFolder", usage = "Destination folder for cloned repositories", metaVar = "PATH")
        public String repositoriesFolder;
    }
    private static class NoopNotificationManager implements INotificationManager {
        @Override
        public NoopNotificationManager start() {
            return this;
        }
        @Override
        public NoopNotificationManager stop() {
            return this;
        }
        @Override
        public boolean isSendingMail() {
            return false;
        }
        @Override
        public void sendMailToAdministrators(String subject, String message) {
        }
        @Override
        public void sendMail(String subject, String message, Collection<String> toAddresses) {
        }
        @Override
        public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
        }
        @Override
        public void send(Mailing mailing) {
        }
    }
}
src/main/java/com/gitblit/GitBlit.java
@@ -15,471 +15,55 @@
 */
package com.gitblit;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.Transport;
import com.gitblit.manager.GitblitManager;
import com.gitblit.manager.IAuthenticationManager;
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;
import com.gitblit.manager.IUserManager;
import com.gitblit.manager.ServicesManager;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
import com.gitblit.models.UserModel;
import com.gitblit.tickets.BranchTicketService;
import com.gitblit.tickets.FileTicketService;
import com.gitblit.tickets.ITicketService;
import com.gitblit.tickets.NullTicketService;
import com.gitblit.tickets.RedisTicketService;
import com.gitblit.transport.ssh.IPublicKeyManager;
import com.gitblit.utils.StringUtils;
import dagger.Module;
import dagger.ObjectGraph;
import dagger.Provides;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
 * GitBlit is the aggregate manager for the Gitblit webapp.  It provides all
 * management functions and also manages some long-running services.
 * GitBlit is the aggregate manager for the Gitblit webapp.  The parent class provides all
 * functionality.  This class exists to not break existing Groovy push hooks.
 *
 * @author James Moger
 *
 */
@Singleton
@Deprecated
public class GitBlit extends GitblitManager {
    private final ObjectGraph injector;
    private final ServicesManager servicesManager;
    private ITicketService ticketService;
    @Inject
    public GitBlit(
            Provider<IPublicKeyManager> publicKeyManagerProvider,
            Provider<ITicketService> ticketServiceProvider,
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
            INotificationManager notificationManager,
            IUserManager userManager,
            IAuthenticationManager authenticationManager,
            IPublicKeyManager publicKeyManager,
            IRepositoryManager repositoryManager,
            IProjectManager projectManager,
            IFederationManager federationManager) {
        super(runtimeManager,
        super(
                publicKeyManagerProvider,
                ticketServiceProvider,
                runtimeManager,
                pluginManager,
                notificationManager,
                userManager,
                authenticationManager,
                publicKeyManager,
                repositoryManager,
                projectManager,
                federationManager);
        this.injector = ObjectGraph.create(getModules());
        this.servicesManager = new ServicesManager(this);
    }
    @Override
    public GitBlit start() {
        super.start();
        logger.info("Starting services manager...");
        servicesManager.start();
        configureTicketService();
        return this;
    }
    @Override
    public GitBlit stop() {
        super.stop();
        servicesManager.stop();
        ticketService.stop();
        return this;
    }
    @Override
    public boolean isServingRepositories() {
        return servicesManager.isServingRepositories();
    }
    @Override
    public boolean isServingHTTP() {
        return servicesManager.isServingHTTP();
    }
    @Override
    public boolean isServingGIT() {
        return servicesManager.isServingGIT();
    }
    @Override
    public boolean isServingSSH() {
        return servicesManager.isServingSSH();
    }
    protected Object [] getModules() {
        return new Object [] { new GitBlitModule()};
    }
    protected boolean acceptPush(Transport byTransport) {
        if (byTransport == null) {
            logger.info("Unknown transport, push rejected!");
            return false;
        }
        Set<Transport> transports = new HashSet<Transport>();
        for (String value : getSettings().getStrings(Keys.git.acceptedPushTransports)) {
            Transport transport = Transport.fromString(value);
            if (transport == null) {
                logger.info(String.format("Ignoring unknown registered transport %s", value));
                continue;
            }
            transports.add(transport);
        }
        if (transports.isEmpty()) {
            // no transports are explicitly specified, all are acceptable
            return true;
        }
        // verify that the transport is permitted
        return transports.contains(byTransport);
    }
    /**
     * Returns a list of repository URLs and the user access permission.
     *
     * @param request
     * @param user
     * @param repository
     * @return a list of repository urls
     */
    @Override
    public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
        if (user == null) {
            user = UserModel.ANONYMOUS;
        }
        String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
        List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
        // http/https url
        if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
            AccessPermission permission = user.getRepositoryPermission(repository).permission;
            if (permission.exceeds(AccessPermission.NONE)) {
                Transport transport = Transport.fromString(request.getScheme());
                if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(transport)) {
                    // downgrade the repo permission for this transport
                    // because it is not an acceptable PUSH transport
                    permission = AccessPermission.CLONE;
                }
                list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
            }
        }
        // ssh daemon url
        String sshDaemonUrl = servicesManager.getSshDaemonUrl(request, user, repository);
        if (!StringUtils.isEmpty(sshDaemonUrl)) {
            AccessPermission permission = user.getRepositoryPermission(repository).permission;
            if (permission.exceeds(AccessPermission.NONE)) {
                if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.SSH)) {
                    // downgrade the repo permission for this transport
                    // because it is not an acceptable PUSH transport
                    permission = AccessPermission.CLONE;
                }
                list.add(new RepositoryUrl(sshDaemonUrl, permission));
            }
        }
        // git daemon url
        String gitDaemonUrl = servicesManager.getGitDaemonUrl(request, user, repository);
        if (!StringUtils.isEmpty(gitDaemonUrl)) {
            AccessPermission permission = servicesManager.getGitDaemonAccessPermission(user, repository);
            if (permission.exceeds(AccessPermission.NONE)) {
                if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.GIT)) {
                    // downgrade the repo permission for this transport
                    // because it is not an acceptable PUSH transport
                    permission = AccessPermission.CLONE;
                }
                list.add(new RepositoryUrl(gitDaemonUrl, permission));
            }
        }
        // add all other urls
        // {0} = repository
        // {1} = username
        for (String url : settings.getStrings(Keys.web.otherUrls)) {
            if (url.contains("{1}")) {
                // external url requires username, only add url IF we have one
                if (!StringUtils.isEmpty(username)) {
                    list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
                }
            } else {
                // external url does not require username
                list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
            }
        }
        // sort transports by highest permission and then by transport security
        Collections.sort(list, new Comparator<RepositoryUrl>() {
            @Override
            public int compare(RepositoryUrl o1, RepositoryUrl o2) {
                if (!o1.isExternal() && o2.isExternal()) {
                    // prefer Gitblit over external
                    return -1;
                } else if (o1.isExternal() && !o2.isExternal()) {
                    // prefer Gitblit over external
                    return 1;
                } else if (o1.isExternal() && o2.isExternal()) {
                    // sort by Transport ordinal
                    return o1.transport.compareTo(o2.transport);
                } else if (o1.permission.exceeds(o2.permission)) {
                    // prefer highest permission
                    return -1;
                } else if (o2.permission.exceeds(o1.permission)) {
                    // prefer highest permission
                    return 1;
                }
                // prefer more secure transports
                return o1.transport.compareTo(o2.transport);
            }
        });
        // consider the user's transport preference
        RepositoryUrl preferredUrl = null;
        Transport preferredTransport = user.getPreferences().getTransport();
        if (preferredTransport != null) {
            Iterator<RepositoryUrl> itr = list.iterator();
            while (itr.hasNext()) {
                RepositoryUrl url = itr.next();
                if (url.transport.equals(preferredTransport)) {
                    itr.remove();
                    preferredUrl = url;
                    break;
                }
            }
        }
        if (preferredUrl != null) {
            list.add(0, preferredUrl);
        }
        return list;
    }
    /**
     * Detect renames and reindex as appropriate.
     */
    @Override
    public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
            boolean isCreate) throws GitBlitException {
        RepositoryModel oldModel = null;
        boolean isRename = !isCreate && !repositoryName.equalsIgnoreCase(repository.name);
        if (isRename) {
            oldModel = repositoryManager.getRepositoryModel(repositoryName);
        }
        super.updateRepositoryModel(repositoryName, repository, isCreate);
        if (isRename && ticketService != null) {
            ticketService.rename(oldModel, repository);
        }
    }
    /**
     * Delete the user and all associated public ssh keys.
     */
    @Override
    public boolean deleteUser(String username) {
        UserModel user = userManager.getUserModel(username);
        return deleteUserModel(user);
    }
    @Override
    public boolean deleteUserModel(UserModel model) {
        boolean success = userManager.deleteUserModel(model);
        if (success) {
            getPublicKeyManager().removeAllKeys(model.username);
        }
        return success;
    }
    /**
     * Delete the repository and all associated tickets.
     */
    @Override
    public boolean deleteRepository(String repositoryName) {
        RepositoryModel repository = repositoryManager.getRepositoryModel(repositoryName);
        return deleteRepositoryModel(repository);
    }
    @Override
    public boolean deleteRepositoryModel(RepositoryModel model) {
        boolean success = repositoryManager.deleteRepositoryModel(model);
        if (success && ticketService != null) {
            ticketService.deleteAll(model);
        }
        return success;
    }
    /**
     * Returns the configured ticket service.
     *
     * @return a ticket service
     */
    @Override
    public ITicketService getTicketService() {
        return ticketService;
    }
    protected void configureTicketService() {
        String clazz = settings.getString(Keys.tickets.service, NullTicketService.class.getName());
        if (StringUtils.isEmpty(clazz)) {
            clazz = NullTicketService.class.getName();
        }
        try {
            Class<? extends ITicketService> serviceClass = (Class<? extends ITicketService>) Class.forName(clazz);
            ticketService = injector.get(serviceClass).start();
            if (ticketService instanceof NullTicketService) {
                logger.warn("No ticket service configured.");
            } else if (ticketService.isReady()) {
                logger.info("{} is ready.", ticketService);
            } else {
                logger.warn("{} is disabled.", ticketService);
            }
        } catch (Exception e) {
            logger.error("failed to create ticket service " + clazz, e);
            ticketService = injector.get(NullTicketService.class).start();
        }
    }
    /**
     * A nested Dagger graph is used for constructor dependency injection of
     * complex classes.
     *
     * @author James Moger
     *
     */
    @Module(
            library = true,
            injects = {
                    IStoredSettings.class,
                    // core managers
                    IRuntimeManager.class,
                    IPluginManager.class,
                    INotificationManager.class,
                    IUserManager.class,
                    IAuthenticationManager.class,
                    IRepositoryManager.class,
                    IProjectManager.class,
                    IFederationManager.class,
                    // the monolithic manager
                    IGitblit.class,
                    // ticket services
                    NullTicketService.class,
                    FileTicketService.class,
                    BranchTicketService.class,
                    RedisTicketService.class
                }
            )
    class GitBlitModule {
        @Provides @Singleton IStoredSettings provideSettings() {
            return settings;
        }
        @Provides @Singleton IRuntimeManager provideRuntimeManager() {
            return runtimeManager;
        }
        @Provides @Singleton IPluginManager providePluginManager() {
            return pluginManager;
        }
        @Provides @Singleton INotificationManager provideNotificationManager() {
            return notificationManager;
        }
        @Provides @Singleton IUserManager provideUserManager() {
            return userManager;
        }
        @Provides @Singleton IAuthenticationManager provideAuthenticationManager() {
            return authenticationManager;
        }
        @Provides @Singleton IRepositoryManager provideRepositoryManager() {
            return repositoryManager;
        }
        @Provides @Singleton IProjectManager provideProjectManager() {
            return projectManager;
        }
        @Provides @Singleton IFederationManager provideFederationManager() {
            return federationManager;
        }
        @Provides @Singleton IGitblit provideGitblit() {
            return GitBlit.this;
        }
        @Provides @Singleton NullTicketService provideNullTicketService() {
            return new NullTicketService(
                    runtimeManager,
                    pluginManager,
                    notificationManager,
                    userManager,
                    repositoryManager);
        }
        @Provides @Singleton FileTicketService provideFileTicketService() {
            return new FileTicketService(
                    runtimeManager,
                    pluginManager,
                    notificationManager,
                    userManager,
                    repositoryManager);
        }
        @Provides @Singleton BranchTicketService provideBranchTicketService() {
            return new BranchTicketService(
                    runtimeManager,
                    pluginManager,
                    notificationManager,
                    userManager,
                    repositoryManager);
        }
        @Provides @Singleton RedisTicketService provideRedisTicketService() {
            return new RedisTicketService(
                    runtimeManager,
                    pluginManager,
                    notificationManager,
                    userManager,
                    repositoryManager);
        }
    }
}
src/main/java/com/gitblit/dagger/DaggerContext.java
File was deleted
src/main/java/com/gitblit/dagger/DaggerFilter.java
File was deleted
src/main/java/com/gitblit/dagger/DaggerServlet.java
File was deleted
src/main/java/com/gitblit/dagger/DaggerWicketFilter.java
File was deleted
src/main/java/com/gitblit/guice/CoreModule.java
New file
@@ -0,0 +1,79 @@
/*
 * 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.guice;
import com.gitblit.FileSettings;
import com.gitblit.GitBlit;
import com.gitblit.IStoredSettings;
import com.gitblit.manager.AuthenticationManager;
import com.gitblit.manager.FederationManager;
import com.gitblit.manager.IAuthenticationManager;
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;
import com.gitblit.manager.IServicesManager;
import com.gitblit.manager.IUserManager;
import com.gitblit.manager.NotificationManager;
import com.gitblit.manager.PluginManager;
import com.gitblit.manager.ProjectManager;
import com.gitblit.manager.RepositoryManager;
import com.gitblit.manager.RuntimeManager;
import com.gitblit.manager.ServicesManager;
import com.gitblit.manager.UserManager;
import com.gitblit.tickets.ITicketService;
import com.gitblit.transport.ssh.IPublicKeyManager;
import com.gitblit.utils.WorkQueue;
import com.google.inject.AbstractModule;
/**
 * CoreModule references all the core business objects.
 *
 * @author James Moger
 *
 */
public class CoreModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(IStoredSettings.class).toInstance(new FileSettings());
        // bind complex providers
        bind(IPublicKeyManager.class).toProvider(IPublicKeyManagerProvider.class);
        bind(ITicketService.class).toProvider(ITicketServiceProvider.class);
        bind(WorkQueue.class).toProvider(WorkQueueProvider.class);
        // core managers
        bind(IRuntimeManager.class).to(RuntimeManager.class);
        bind(IPluginManager.class).to(PluginManager.class);
        bind(INotificationManager.class).to(NotificationManager.class);
        bind(IUserManager.class).to(UserManager.class);
        bind(IAuthenticationManager.class).to(AuthenticationManager.class);
        bind(IRepositoryManager.class).to(RepositoryManager.class);
        bind(IProjectManager.class).to(ProjectManager.class);
        bind(IFederationManager.class).to(FederationManager.class);
        // the monolithic manager
        bind(IGitblit.class).to(GitBlit.class);
        // manager for long-running daemons and services
        bind(IServicesManager.class).to(ServicesManager.class);
    }
}
src/main/java/com/gitblit/guice/IPublicKeyManagerProvider.java
New file
@@ -0,0 +1,72 @@
/*
 * 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.guice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.transport.ssh.FileKeyManager;
import com.gitblit.transport.ssh.IPublicKeyManager;
import com.gitblit.transport.ssh.NullKeyManager;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
 * Provides a lazily-instantiated IPublicKeyManager configured from IStoredSettings.
 *
 * @author James Moger
 *
 */
@Singleton
public class IPublicKeyManagerProvider implements Provider<IPublicKeyManager> {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final IRuntimeManager runtimeManager;
    private volatile IPublicKeyManager manager;
    @Inject
    public IPublicKeyManagerProvider(IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
    }
    @Override
    public synchronized IPublicKeyManager get() {
        if (manager != null) {
            return manager;
        }
        IStoredSettings settings = runtimeManager.getSettings();
        String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName());
        if (StringUtils.isEmpty(clazz)) {
            clazz = FileKeyManager.class.getName();
        }
        try {
            Class<? extends IPublicKeyManager> mgrClass = (Class<? extends IPublicKeyManager>) Class.forName(clazz);
            manager = runtimeManager.getInjector().getInstance(mgrClass);
        } catch (Exception e) {
            logger.error("failed to create public key manager", e);
            manager = new NullKeyManager();
        }
        return manager;
    }
}
src/main/java/com/gitblit/guice/ITicketServiceProvider.java
New file
@@ -0,0 +1,73 @@
/*
 * 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.guice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.tickets.ITicketService;
import com.gitblit.tickets.NullTicketService;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
 * Provides a lazily-instantiated ITicketService configured from IStoredSettings.
 *
 * @author James Moger
 *
 */
@Singleton
public class ITicketServiceProvider implements Provider<ITicketService> {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final IRuntimeManager runtimeManager;
    private volatile ITicketService service;
    @Inject
    public ITicketServiceProvider(IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
    }
    @Override
    public synchronized ITicketService get() {
        if (service != null) {
            return service;
        }
        IStoredSettings settings = runtimeManager.getSettings();
        String clazz = settings.getString(Keys.tickets.service, NullTicketService.class.getName());
        if (StringUtils.isEmpty(clazz)) {
            clazz = NullTicketService.class.getName();
        }
        try {
            Class<? extends ITicketService> serviceClass = (Class<? extends ITicketService>) Class.forName(clazz);
            service = runtimeManager.getInjector().getInstance(serviceClass);
        } catch (Exception e) {
            logger.error("failed to create ticket service", e);
            service = runtimeManager.getInjector().getInstance(NullTicketService.class);
        }
        return service;
    }
}
src/main/java/com/gitblit/guice/WebModule.java
New file
@@ -0,0 +1,105 @@
/*
 * 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.guice;
import java.util.HashMap;
import java.util.Map;
import com.gitblit.Constants;
import com.gitblit.servlet.BranchGraphServlet;
import com.gitblit.servlet.DownloadZipFilter;
import com.gitblit.servlet.DownloadZipServlet;
import com.gitblit.servlet.EnforceAuthenticationFilter;
import com.gitblit.servlet.FederationServlet;
import com.gitblit.servlet.GitFilter;
import com.gitblit.servlet.GitServlet;
import com.gitblit.servlet.LogoServlet;
import com.gitblit.servlet.PagesFilter;
import com.gitblit.servlet.PagesServlet;
import com.gitblit.servlet.ProxyFilter;
import com.gitblit.servlet.PtServlet;
import com.gitblit.servlet.RawFilter;
import com.gitblit.servlet.RawServlet;
import com.gitblit.servlet.RobotsTxtServlet;
import com.gitblit.servlet.RpcFilter;
import com.gitblit.servlet.RpcServlet;
import com.gitblit.servlet.SparkleShareInviteServlet;
import com.gitblit.servlet.SyndicationFilter;
import com.gitblit.servlet.SyndicationServlet;
import com.gitblit.wicket.GitblitWicketFilter;
import com.google.common.base.Joiner;
import com.google.inject.servlet.ServletModule;
/**
 * Defines all the web servlets & filters.
 *
 * @author James Moger
 *
 */
public class WebModule extends ServletModule {
    final static String ALL = "/*";
    @Override
    protected void configureServlets() {
        // servlets
        serve(fuzzy(Constants.R_PATH), fuzzy(Constants.GIT_PATH)).with(GitServlet.class);
        serve(fuzzy(Constants.RAW_PATH)).with(RawServlet.class);
        serve(fuzzy(Constants.PAGES)).with(PagesServlet.class);
        serve(fuzzy(Constants.RPC_PATH)).with(RpcServlet.class);
        serve(fuzzy(Constants.ZIP_PATH)).with(DownloadZipServlet.class);
        serve(fuzzy(Constants.SYNDICATION_PATH)).with(SyndicationServlet.class);
        serve(fuzzy(Constants.FEDERATION_PATH)).with(FederationServlet.class);
        serve(fuzzy(Constants.SPARKLESHARE_INVITE_PATH)).with(SparkleShareInviteServlet.class);
        serve(fuzzy(Constants.BRANCH_GRAPH_PATH)).with(BranchGraphServlet.class);
        serve(Constants.PT_PATH).with(PtServlet.class);
        serve("/robots.txt").with(RobotsTxtServlet.class);
        serve("/logo.png").with(LogoServlet.class);
        // global filters
        filter(ALL).through(ProxyFilter.class);
        filter(ALL).through(EnforceAuthenticationFilter.class);
        // security filters
        filter(fuzzy(Constants.R_PATH), fuzzy(Constants.GIT_PATH)).through(GitFilter.class);
        filter(fuzzy(Constants.RAW_PATH)).through(RawFilter.class);
        filter(fuzzy(Constants.PAGES)).through(PagesFilter.class);
        filter(fuzzy(Constants.RPC_PATH)).through(RpcFilter.class);
        filter(fuzzy(Constants.ZIP_PATH)).through(DownloadZipFilter.class);
        filter(fuzzy(Constants.SYNDICATION_PATH)).through(SyndicationFilter.class);
        // Wicket
        String toIgnore = Joiner.on(",").join(Constants.R_PATH, Constants.GIT_PATH, Constants.RAW_PATH,
                Constants.PAGES, Constants.RPC_PATH, Constants.ZIP_PATH, Constants.SYNDICATION_PATH,
                Constants.FEDERATION_PATH, Constants.SPARKLESHARE_INVITE_PATH, Constants.BRANCH_GRAPH_PATH,
                Constants.PT_PATH, "/robots.txt", "/logo.png");
        Map<String, String> params = new HashMap<String, String>();
        params.put(GitblitWicketFilter.FILTER_MAPPING_PARAM, ALL);
        params.put(GitblitWicketFilter.IGNORE_PATHS_PARAM, toIgnore);
        filter(ALL).through(GitblitWicketFilter.class, params);
    }
    private String fuzzy(String path) {
        if (path.endsWith(ALL)) {
            return path;
        } else if (path.endsWith("/")) {
            return path + "*";
        }
        return path + ALL;
    }
}
src/main/java/com/gitblit/guice/WorkQueueProvider.java
New file
@@ -0,0 +1,57 @@
/*
 * 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.guice;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.WorkQueue;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
 * Provides a lazily-instantiated WorkQueue configured from IStoredSettings.
 *
 * @author James Moger
 *
 */
@Singleton
public class WorkQueueProvider implements Provider<WorkQueue> {
    private final IRuntimeManager runtimeManager;
    private volatile WorkQueue workQueue;
    @Inject
    public WorkQueueProvider(IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
    }
    @Override
    public synchronized WorkQueue get() {
        if (workQueue != null) {
            return workQueue;
        }
        IStoredSettings settings = runtimeManager.getSettings();
        int defaultThreadPoolSize = settings.getInteger(Keys.execution.defaultThreadPoolSize, 1);
        IdGenerator idGenerator = new IdGenerator();
        workQueue = new WorkQueue(idGenerator, defaultThreadPoolSize);
        return workQueue;
    }
}
src/main/java/com/gitblit/manager/AuthenticationManager.java
@@ -53,6 +53,8 @@
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.X509Utils.X509Metadata;
import com.gitblit.wicket.GitBlitWebSession;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * The authentication manager handles user login & logout.
@@ -60,6 +62,7 @@
 * @author James Moger
 *
 */
@Singleton
public class AuthenticationManager implements IAuthenticationManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -76,6 +79,7 @@
    private final Map<String, String> legacyRedirects;
    @Inject
    public AuthenticationManager(
            IRuntimeManager runtimeManager,
            IUserManager userManager) {
src/main/java/com/gitblit/manager/FederationManager.java
@@ -45,6 +45,8 @@
import com.gitblit.utils.FederationUtils;
import com.gitblit.utils.JsonUtils;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * Federation manager controls all aspects of handling federation sets, tokens,
@@ -53,6 +55,7 @@
 * @author James Moger
 *
 */
@Singleton
public class FederationManager implements IFederationManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -70,6 +73,7 @@
    private final IRepositoryManager repositoryManager;
    @Inject
    public FederationManager(
            IRuntimeManager runtimeManager,
            INotificationManager notificationManager,
src/main/java/com/gitblit/manager/GitblitManager.java
@@ -49,12 +49,10 @@
import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.FederationRequest;
import com.gitblit.Constants.FederationToken;
import com.gitblit.GitBlitException;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.models.FederationModel;
import com.gitblit.models.FederationProposal;
import com.gitblit.models.FederationSet;
@@ -68,7 +66,6 @@
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
import com.gitblit.models.SearchResult;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
@@ -79,7 +76,6 @@
import com.gitblit.transport.ssh.IPublicKeyManager;
import com.gitblit.transport.ssh.SshKey;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.HttpUtils;
import com.gitblit.utils.JsonUtils;
import com.gitblit.utils.ObjectCache;
import com.gitblit.utils.StringUtils;
@@ -87,6 +83,10 @@
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.Provider;
/**
 * GitblitManager is an aggregate interface delegate.  It implements all the manager
@@ -100,11 +100,16 @@
 * @author James Moger
 *
 */
@Singleton
public class GitblitManager implements IGitblit {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    protected final ObjectCache<Collection<GitClientApplication>> clientApplications = new ObjectCache<Collection<GitClientApplication>>();
    protected final Provider<IPublicKeyManager> publicKeyManagerProvider;
    protected final Provider<ITicketService> ticketServiceProvider;
    protected final IStoredSettings settings;
@@ -118,24 +123,27 @@
    protected final IAuthenticationManager authenticationManager;
    protected final IPublicKeyManager publicKeyManager;
    protected final IRepositoryManager repositoryManager;
    protected final IProjectManager projectManager;
    protected final IFederationManager federationManager;
    @Inject
    public GitblitManager(
            Provider<IPublicKeyManager> publicKeyManagerProvider,
            Provider<ITicketService> ticketServiceProvider,
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
            INotificationManager notificationManager,
            IUserManager userManager,
            IAuthenticationManager authenticationManager,
            IPublicKeyManager publicKeyManager,
            IRepositoryManager repositoryManager,
            IProjectManager projectManager,
            IFederationManager federationManager) {
        this.publicKeyManagerProvider = publicKeyManagerProvider;
        this.ticketServiceProvider = ticketServiceProvider;
        this.settings = runtimeManager.getSettings();
        this.runtimeManager = runtimeManager;
@@ -143,7 +151,6 @@
        this.notificationManager = notificationManager;
        this.userManager = userManager;
        this.authenticationManager = authenticationManager;
        this.publicKeyManager = publicKeyManager;
        this.repositoryManager = repositoryManager;
        this.projectManager = projectManager;
        this.federationManager = federationManager;
@@ -350,66 +357,6 @@
    }
    /**
     * Returns a list of repository URLs and the user access permission.
     *
     * @param request
     * @param user
     * @param repository
     * @return a list of repository urls
     */
    @Override
    public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
        if (user == null) {
            user = UserModel.ANONYMOUS;
        }
        String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
        List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
        // http/https url
        if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
            AccessPermission permission = user.getRepositoryPermission(repository).permission;
            if (permission.exceeds(AccessPermission.NONE)) {
                list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
            }
        }
        // add all other urls
        // {0} = repository
        // {1} = username
        for (String url : settings.getStrings(Keys.web.otherUrls)) {
            if (url.contains("{1}")) {
                // external url requires username, only add url IF we have one
                if (!StringUtils.isEmpty(username)) {
                    list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
                }
            } else {
                // external url does not require username
                list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
            }
        }
        return list;
    }
    protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) {
        String gitblitUrl = settings.getString(Keys.web.canonicalUrl, null);
        if (StringUtils.isEmpty(gitblitUrl)) {
            gitblitUrl = HttpUtils.getGitblitURL(request);
        }
        StringBuilder sb = new StringBuilder();
        sb.append(gitblitUrl);
        sb.append(Constants.R_PATH);
        sb.append(repository.name);
        // inject username into repository url if authentication is required
        if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE)
                && !StringUtils.isEmpty(username)) {
            sb.insert(sb.indexOf("://") + 3, username + "@");
        }
        return sb.toString();
    }
    /**
     * Returns the list of custom client applications to be used for the
     * repository url panel;
     *
@@ -535,18 +482,14 @@
        }
    }
    /**
     * Throws an exception if trying to get a ticket service.
     *
     */
    @Override
    public ITicketService getTicketService() {
        throw new RuntimeException("This class does not have a ticket service!");
        return ticketServiceProvider.get();
    }
    @Override
    public IPublicKeyManager getPublicKeyManager() {
        return publicKeyManager;
        return publicKeyManagerProvider.get();
    }
    /*
@@ -597,26 +540,6 @@
    }
    @Override
    public boolean isServingRepositories() {
        return runtimeManager.isServingRepositories();
    }
    @Override
    public boolean isServingHTTP() {
        return runtimeManager.isServingHTTP();
    }
    @Override
    public boolean isServingGIT() {
        return runtimeManager.isServingGIT();
    }
    @Override
    public boolean isServingSSH() {
        return runtimeManager.isServingSSH();
    }
    @Override
    public TimeZone getTimezone() {
        return runtimeManager.getTimezone();
    }
@@ -654,6 +577,11 @@
    @Override
    public ServerStatus getStatus() {
        return runtimeManager.getStatus();
    }
    @Override
    public Injector getInjector() {
        return runtimeManager.getInjector();
    }
    /*
@@ -781,11 +709,6 @@
    }
    @Override
    public boolean deleteUser(String username) {
        return userManager.deleteUser(username);
    }
    @Override
    public UserModel getUserModel(String username) {
        return userManager.getUserModel(username);
    }
@@ -826,8 +749,22 @@
    }
    @Override
    public boolean deleteUser(String username) {
        // delegate to deleteUserModel() to delete public ssh keys
        UserModel user = userManager.getUserModel(username);
        return deleteUserModel(user);
    }
    /**
     * Delete the user and all associated public ssh keys.
     */
    @Override
    public boolean deleteUserModel(UserModel model) {
        return userManager.deleteUserModel(model);
        boolean success = userManager.deleteUserModel(model);
        if (success) {
            getPublicKeyManager().removeAllKeys(model.username);
        }
        return success;
    }
    @Override
@@ -1023,10 +960,23 @@
        return repositoryManager.getRepositoryDefaultMetrics(model, repository);
    }
    /**
     * Detect renames and reindex as appropriate.
     */
    @Override
    public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
            boolean isCreate) throws GitBlitException {
        RepositoryModel oldModel = null;
        boolean isRename = !isCreate && !repositoryName.equalsIgnoreCase(repository.name);
        if (isRename) {
            oldModel = repositoryManager.getRepositoryModel(repositoryName);
        }
        repositoryManager.updateRepositoryModel(repositoryName, repository, isCreate);
        if (isRename && ticketServiceProvider.get() != null) {
            ticketServiceProvider.get().rename(oldModel, repository);
        }
    }
    @Override
@@ -1039,14 +989,23 @@
        return repositoryManager.canDelete(model);
    }
    /**
     * Delete the repository and all associated tickets.
     */
    @Override
    public boolean deleteRepositoryModel(RepositoryModel model) {
        return repositoryManager.deleteRepositoryModel(model);
        boolean success = repositoryManager.deleteRepositoryModel(model);
        if (success && ticketServiceProvider.get() != null) {
            ticketServiceProvider.get().deleteAll(model);
        }
        return success;
    }
    @Override
    public boolean deleteRepository(String repositoryName) {
        return repositoryManager.deleteRepository(repositoryName);
        // delegate to deleteRepositoryModel() to destroy indexed tickets
        RepositoryModel repository = repositoryManager.getRepositoryModel(repositoryName);
        return deleteRepositoryModel(repository);
    }
    @Override
src/main/java/com/gitblit/manager/IGitblit.java
@@ -16,14 +16,10 @@
package com.gitblit.manager;
import java.util.Collection;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.gitblit.GitBlitException;
import com.gitblit.models.GitClientApplication;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.tickets.ITicketService;
@@ -38,17 +34,6 @@
                                    IRepositoryManager,
                                    IProjectManager,
                                    IFederationManager {
    /**
     * Returns a list of repository URLs and the user access permission.
     *
     * @param request
     * @param user
     * @param repository
     * @return a list of repository urls
     * @since 1.4.0
     */
    List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository);
    /**
     * Creates a complete user object.
src/main/java/com/gitblit/manager/IRuntimeManager.java
@@ -24,8 +24,11 @@
import com.gitblit.IStoredSettings;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
import com.google.inject.Injector;
public interface IRuntimeManager extends IManager {
    Injector getInjector();
    void setBaseFolder(File folder);
@@ -46,42 +49,6 @@
      * @since 1.5.1
     */
    Locale getLocale();
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * or if it is merely a repository viewer.
     *
     * @return true if Gitblit is serving repositories
      * @since 1.4.0
     */
    boolean isServingRepositories();
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over HTTP.
     *
     * @return true if Gitblit is serving repositories over HTTP
      * @since 1.6.0
     */
    boolean isServingHTTP();
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over the GIT Daemon protocol.
     *
     * @return true if Gitblit is serving repositories over the GIT Daemon protocol
      * @since 1.6.0
     */
    boolean isServingGIT();
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over the SSH protocol.
     *
     * @return true if Gitblit is serving repositories over the SSH protocol
      * @since 1.6.0
     */
    boolean isServingSSH();
    /**
     * Determine if this Gitblit instance is running in debug mode
src/main/java/com/gitblit/manager/IServicesManager.java
New file
@@ -0,0 +1,75 @@
/*
 * 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 javax.servlet.http.HttpServletRequest;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
import com.gitblit.models.UserModel;
public interface IServicesManager extends IManager {
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * or if it is merely a repository viewer.
     *
     * @return true if Gitblit is serving repositories
      * @since 1.7.0
     */
    boolean isServingRepositories();
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over HTTP.
     *
     * @return true if Gitblit is serving repositories over HTTP
      * @since 1.7.0
     */
    boolean isServingHTTP();
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over the GIT Daemon protocol.
     *
     * @return true if Gitblit is serving repositories over the GIT Daemon protocol
      * @since 1.7.0
     */
    boolean isServingGIT();
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over the SSH protocol.
     *
     * @return true if Gitblit is serving repositories over the SSH protocol
      * @since 1.7.0
     */
    boolean isServingSSH();
    /**
     * Returns a list of repository URLs and the user access permission.
     *
     * @param request
     * @param user
     * @param repository
     * @return a list of repository urls
     * @since 1.7.0
     */
    List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository);
}
src/main/java/com/gitblit/manager/NotificationManager.java
@@ -29,6 +29,8 @@
import com.gitblit.Keys;
import com.gitblit.models.Mailing;
import com.gitblit.service.MailService;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * The notification manager dispatches notifications.  Currently, email is the
@@ -38,6 +40,7 @@
 * @author James Moger
 *
 */
@Singleton
public class NotificationManager implements INotificationManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -48,6 +51,7 @@
    private final MailService mailService;
    @Inject
    public NotificationManager(IStoredSettings settings) {
        this.settings = settings;
        this.mailService = new MailService(settings);
src/main/java/com/gitblit/manager/PluginManager.java
@@ -37,7 +37,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.fortsoft.pf4j.DefaultExtensionFinder;
import ro.fortsoft.pf4j.DefaultPluginManager;
import ro.fortsoft.pf4j.ExtensionFinder;
import ro.fortsoft.pf4j.PluginClassLoader;
import ro.fortsoft.pf4j.PluginState;
import ro.fortsoft.pf4j.PluginStateEvent;
@@ -58,6 +60,8 @@
import com.gitblit.utils.StringUtils;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * The plugin manager maintains the lifecycle of plugins. It is exposed as
@@ -68,32 +72,23 @@
 * @author James Moger
 *
 */
@Singleton
public class PluginManager implements IPluginManager, PluginStateListener {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final DefaultPluginManager pf4j;
    private final IRuntimeManager runtimeManager;
    private DefaultPluginManager pf4j;
    // timeout defaults of Maven 3.0.4 in seconds
    private int connectTimeout = 20;
    private int readTimeout = 12800;
    @Inject
    public PluginManager(IRuntimeManager runtimeManager) {
        File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
        dir.mkdirs();
        this.runtimeManager = runtimeManager;
        this.pf4j = new DefaultPluginManager(dir);
        try {
            Version systemVersion = Version.createVersion(Constants.getVersion());
            pf4j.setSystemVersion(systemVersion);
        } catch (Exception e) {
            logger.error(null, e);
        }
    }
    @Override
@@ -108,6 +103,42 @@
    @Override
    public PluginManager start() {
        File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
        dir.mkdirs();
        pf4j = new DefaultPluginManager(dir) {
            @Override
            protected ExtensionFinder createExtensionFinder() {
                DefaultExtensionFinder extensionFinder = new DefaultExtensionFinder(this) {
                    @Override
                    protected ExtensionFactory createExtensionFactory() {
                        return new ExtensionFactory() {
                            @Override
                            public Object create(Class<?> extensionType) {
                                // instantiate && inject the extension
                                logger.debug("Create instance for extension '{}'", extensionType.getName());
                                try {
                                    return runtimeManager.getInjector().getInstance(extensionType);
                                } catch (Exception e) {
                                    logger.error(e.getMessage(), e);
                                }
                                return null;
                            }
                        };
                    }
                };
                addPluginStateListener(extensionFinder);
                return extensionFinder;
            }
        };
        try {
            Version systemVersion = Version.createVersion(Constants.getVersion());
            pf4j.setSystemVersion(systemVersion);
        } catch (Exception e) {
            logger.error(null, e);
        }
        pf4j.loadPlugins();
        logger.debug("Starting plugins");
        pf4j.startPlugins();
src/main/java/com/gitblit/manager/ProjectManager.java
@@ -41,6 +41,8 @@
import com.gitblit.utils.ModelUtils;
import com.gitblit.utils.ObjectCache;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * Project manager handles project-related functions.
@@ -48,6 +50,7 @@
 * @author James Moger
 *
 */
@Singleton
public class ProjectManager implements IProjectManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -68,6 +71,7 @@
    private FileBasedConfig projectConfigs;
    @Inject
    public ProjectManager(
            IRuntimeManager runtimeManager,
            IUserManager userManager,
src/main/java/com/gitblit/manager/RepositoryManager.java
@@ -89,6 +89,8 @@
import com.gitblit.utils.ObjectCache;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * Repository manager creates, updates, deletes and caches git repositories.  It
@@ -97,6 +99,7 @@
 * @author James Moger
 *
 */
@Singleton
public class RepositoryManager implements IRepositoryManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -119,7 +122,7 @@
    private final IUserManager userManager;
    private final File repositoriesFolder;
    private File repositoriesFolder;
    private LuceneService luceneExecutor;
@@ -127,6 +130,7 @@
    private MirrorService mirrorExecutor;
    @Inject
    public RepositoryManager(
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
@@ -136,11 +140,11 @@
        this.runtimeManager = runtimeManager;
        this.pluginManager = pluginManager;
        this.userManager = userManager;
        this.repositoriesFolder = runtimeManager.getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
    }
    @Override
    public RepositoryManager start() {
        repositoriesFolder = runtimeManager.getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
        logger.info("Repositories folder : {}", repositoriesFolder.getAbsolutePath());
        // initialize utilities
@@ -1934,21 +1938,19 @@
    }
    protected void confirmWriteAccess() {
        if (runtimeManager.isServingRepositories()) {
            try {
                if (!getRepositoriesFolder().exists()) {
                    getRepositoriesFolder().mkdirs();
                }
                File file = File.createTempFile(".test-", ".txt", getRepositoriesFolder());
                file.delete();
            } catch (Exception e) {
                logger.error("");
                logger.error(Constants.BORDER2);
                logger.error("Please check filesystem permissions!");
                logger.error("FAILED TO WRITE TO REPOSITORIES FOLDER!!", e);
                logger.error(Constants.BORDER2);
                logger.error("");
        try {
            if (!getRepositoriesFolder().exists()) {
                getRepositoriesFolder().mkdirs();
            }
            File file = File.createTempFile(".test-", ".txt", getRepositoriesFolder());
            file.delete();
        } catch (Exception e) {
            logger.error("");
            logger.error(Constants.BORDER2);
            logger.error("Please check filesystem permissions!");
            logger.error("FAILED TO WRITE TO REPOSITORIES FOLDER!!", e);
            logger.error(Constants.BORDER2);
            logger.error("");
        }
    }
}
src/main/java/com/gitblit/manager/RuntimeManager.java
@@ -32,7 +32,11 @@
import com.gitblit.models.ServerStatus;
import com.gitblit.models.SettingModel;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
@Singleton
public class RuntimeManager implements IRuntimeManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -47,6 +51,10 @@
    private TimeZone timezone;
    @Inject
    private Injector injector;
    @Inject
    public RuntimeManager(IStoredSettings settings) {
        this(settings, null);
    }
@@ -72,6 +80,11 @@
    @Override
    public RuntimeManager stop() {
        return this;
    }
    @Override
    public Injector getInjector() {
        return injector;
    }
    @Override
@@ -109,52 +122,6 @@
        }
//        settingsModel.pushScripts = getAllScripts();
        return settingsModel;
    }
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * or if it is merely a repository viewer.
     *
     * @return true if Gitblit is serving repositories
     */
    @Override
    public boolean isServingRepositories() {
        return isServingHTTP()
                || isServingGIT()
                || isServingSSH();
    }
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over the HTTP protocol.
     *
     * @return true if Gitblit is serving repositories over the HTTP protocol
     */
    @Override
    public boolean isServingHTTP() {
        return settings.getBoolean(Keys.git.enableGitServlet, true);
    }
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over the Git Daemon protocol.
     *
     * @return true if Gitblit is serving repositories over the Git Daemon protocol
     */
    @Override
    public boolean isServingGIT() {
        return settings.getInteger(Keys.git.daemonPort, 0) > 0;
    }
    /**
     * Determine if this Gitblit instance is actively serving git repositories
     * over the SSH protocol.
     *
     * @return true if Gitblit is serving repositories over the SSH protocol
     */
    @Override
    public boolean isServingSSH() {
        return settings.getInteger(Keys.git.sshPort, 0) > 0;
    }
    /**
src/main/java/com/gitblit/manager/ServicesManager.java
@@ -18,9 +18,15 @@
import java.io.IOException;
import java.net.URI;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -30,9 +36,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.FederationToken;
import com.gitblit.Constants.Transport;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.fanout.FanoutNioService;
@@ -40,14 +48,18 @@
import com.gitblit.fanout.FanoutSocketService;
import com.gitblit.models.FederationModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
import com.gitblit.models.UserModel;
import com.gitblit.service.FederationPullService;
import com.gitblit.transport.git.GitDaemon;
import com.gitblit.transport.ssh.SshDaemon;
import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.HttpUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;
import com.gitblit.utils.WorkQueue;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
 * Services manager manages long-running services/processes that either have no
@@ -57,19 +69,18 @@
 * @author James Moger
 *
 */
public class ServicesManager implements IManager {
@Singleton
public class ServicesManager implements IServicesManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(5);
    private final Provider<WorkQueue> workQueueProvider;
    private final IStoredSettings settings;
    private final IGitblit gitblit;
    private final IdGenerator idGenerator;
    private final WorkQueue workQueue;
    private FanoutService fanoutService;
@@ -77,12 +88,16 @@
    private SshDaemon sshDaemon;
    public ServicesManager(IGitblit gitblit) {
        this.settings = gitblit.getSettings();
    @Inject
    public ServicesManager(
            Provider<WorkQueue> workQueueProvider,
            IStoredSettings settings,
            IGitblit gitblit) {
        this.workQueueProvider = workQueueProvider;
        this.settings = settings;
        this.gitblit = gitblit;
        int defaultThreadPoolSize = settings.getInteger(Keys.execution.defaultThreadPoolSize, 1);
        this.idGenerator = new IdGenerator();
        this.workQueue = new WorkQueue(idGenerator, defaultThreadPoolSize);
    }
    @Override
@@ -107,24 +122,181 @@
        if (sshDaemon != null) {
            sshDaemon.stop();
        }
        workQueue.stop();
        workQueueProvider.get().stop();
        return this;
    }
    protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) {
        String gitblitUrl = settings.getString(Keys.web.canonicalUrl, null);
        if (StringUtils.isEmpty(gitblitUrl)) {
            gitblitUrl = HttpUtils.getGitblitURL(request);
        }
        StringBuilder sb = new StringBuilder();
        sb.append(gitblitUrl);
        sb.append(Constants.R_PATH);
        sb.append(repository.name);
        // inject username into repository url if authentication is required
        if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE)
                && !StringUtils.isEmpty(username)) {
            sb.insert(sb.indexOf("://") + 3, username + "@");
        }
        return sb.toString();
    }
    /**
     * Returns a list of repository URLs and the user access permission.
     *
     * @param request
     * @param user
     * @param repository
     * @return a list of repository urls
     */
    @Override
    public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
        if (user == null) {
            user = UserModel.ANONYMOUS;
        }
        String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
        List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
        // http/https url
        if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
            AccessPermission permission = user.getRepositoryPermission(repository).permission;
            if (permission.exceeds(AccessPermission.NONE)) {
                Transport transport = Transport.fromString(request.getScheme());
                if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(transport)) {
                    // downgrade the repo permission for this transport
                    // because it is not an acceptable PUSH transport
                    permission = AccessPermission.CLONE;
                }
                list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
            }
        }
        // ssh daemon url
        String sshDaemonUrl = getSshDaemonUrl(request, user, repository);
        if (!StringUtils.isEmpty(sshDaemonUrl)) {
            AccessPermission permission = user.getRepositoryPermission(repository).permission;
            if (permission.exceeds(AccessPermission.NONE)) {
                if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.SSH)) {
                    // downgrade the repo permission for this transport
                    // because it is not an acceptable PUSH transport
                    permission = AccessPermission.CLONE;
                }
                list.add(new RepositoryUrl(sshDaemonUrl, permission));
            }
        }
        // git daemon url
        String gitDaemonUrl = getGitDaemonUrl(request, user, repository);
        if (!StringUtils.isEmpty(gitDaemonUrl)) {
            AccessPermission permission = getGitDaemonAccessPermission(user, repository);
            if (permission.exceeds(AccessPermission.NONE)) {
                if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.GIT)) {
                    // downgrade the repo permission for this transport
                    // because it is not an acceptable PUSH transport
                    permission = AccessPermission.CLONE;
                }
                list.add(new RepositoryUrl(gitDaemonUrl, permission));
            }
        }
        // add all other urls
        // {0} = repository
        // {1} = username
        for (String url : settings.getStrings(Keys.web.otherUrls)) {
            if (url.contains("{1}")) {
                // external url requires username, only add url IF we have one
                if (!StringUtils.isEmpty(username)) {
                    list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
                }
            } else {
                // external url does not require username
                list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
            }
        }
        // sort transports by highest permission and then by transport security
        Collections.sort(list, new Comparator<RepositoryUrl>() {
            @Override
            public int compare(RepositoryUrl o1, RepositoryUrl o2) {
                if (!o1.isExternal() && o2.isExternal()) {
                    // prefer Gitblit over external
                    return -1;
                } else if (o1.isExternal() && !o2.isExternal()) {
                    // prefer Gitblit over external
                    return 1;
                } else if (o1.isExternal() && o2.isExternal()) {
                    // sort by Transport ordinal
                    return o1.transport.compareTo(o2.transport);
                } else if (o1.permission.exceeds(o2.permission)) {
                    // prefer highest permission
                    return -1;
                } else if (o2.permission.exceeds(o1.permission)) {
                    // prefer highest permission
                    return 1;
                }
                // prefer more secure transports
                return o1.transport.compareTo(o2.transport);
            }
        });
        // consider the user's transport preference
        RepositoryUrl preferredUrl = null;
        Transport preferredTransport = user.getPreferences().getTransport();
        if (preferredTransport != null) {
            Iterator<RepositoryUrl> itr = list.iterator();
            while (itr.hasNext()) {
                RepositoryUrl url = itr.next();
                if (url.transport.equals(preferredTransport)) {
                    itr.remove();
                    preferredUrl = url;
                    break;
                }
            }
        }
        if (preferredUrl != null) {
            list.add(0, preferredUrl);
        }
        return list;
    }
    /* (non-Javadoc)
     * @see com.gitblit.manager.IServicesManager#isServingRepositories()
     */
    @Override
    public boolean isServingRepositories() {
        return isServingHTTP()
                || isServingGIT()
                || isServingSSH();
    }
    /* (non-Javadoc)
     * @see com.gitblit.manager.IServicesManager#isServingHTTP()
     */
    @Override
    public boolean isServingHTTP() {
        return settings.getBoolean(Keys.git.enableGitServlet, true);
    }
    /* (non-Javadoc)
     * @see com.gitblit.manager.IServicesManager#isServingGIT()
     */
    @Override
    public boolean isServingGIT() {
        return gitDaemon != null && gitDaemon.isRunning();
    }
    /* (non-Javadoc)
     * @see com.gitblit.manager.IServicesManager#isServingSSH()
     */
    @Override
    public boolean isServingSSH() {
        return sshDaemon != null && sshDaemon.isRunning();
    }
@@ -158,6 +330,32 @@
        }
    }
    protected boolean acceptPush(Transport byTransport) {
        if (byTransport == null) {
            logger.info("Unknown transport, push rejected!");
            return false;
        }
        Set<Transport> transports = new HashSet<Transport>();
        for (String value : settings.getStrings(Keys.git.acceptedPushTransports)) {
            Transport transport = Transport.fromString(value);
            if (transport == null) {
                logger.info(String.format("Ignoring unknown registered transport %s", value));
                continue;
            }
            transports.add(transport);
        }
        if (transports.isEmpty()) {
            // no transports are explicitly specified, all are acceptable
            return true;
        }
        // verify that the transport is permitted
        return transports.contains(byTransport);
    }
    protected void configureGitDaemon() {
        int port = settings.getInteger(Keys.git.daemonPort, 0);
        String bindInterface = settings.getString(Keys.git.daemonBindInterface, "localhost");
@@ -179,7 +377,7 @@
        String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost");
        if (port > 0) {
            try {
                sshDaemon = new SshDaemon(gitblit, workQueue);
                sshDaemon = new SshDaemon(gitblit, workQueueProvider.get());
                sshDaemon.start();
            } catch (IOException e) {
                sshDaemon = null;
@@ -285,7 +483,7 @@
     */
    protected String getHostname(HttpServletRequest request) {
        String hostname = request.getServerName();
        String canonicalUrl = gitblit.getSettings().getString(Keys.web.canonicalUrl, null);
        String canonicalUrl = settings.getString(Keys.web.canonicalUrl, null);
        if (!StringUtils.isEmpty(canonicalUrl)) {
            try {
                URI uri = new URI(canonicalUrl);
src/main/java/com/gitblit/manager/UserManager.java
@@ -36,6 +36,8 @@
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * The user manager manages persistence and retrieval of users and teams.
@@ -43,6 +45,7 @@
 * @author James Moger
 *
 */
@Singleton
public class UserManager implements IUserManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -57,6 +60,7 @@
    private IUserService userService;
    @Inject
    public UserManager(IRuntimeManager runtimeManager, IPluginManager pluginManager) {
        this.settings = runtimeManager.getSettings();
        this.runtimeManager = runtimeManager;
src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java
@@ -19,20 +19,18 @@
import java.text.MessageFormat;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * The AccessRestrictionFilter is an AuthenticationFilter that confirms that the
@@ -54,11 +52,15 @@
    protected IRepositoryManager repositoryManager;
    @Override
    protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
        super.inject(dagger, filterConfig);
        this.runtimeManager = dagger.get(IRuntimeManager.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
    protected AccessRestrictionFilter(
            IRuntimeManager runtimeManager,
            IAuthenticationManager authenticationManager,
            IRepositoryManager repositoryManager) {
        super(authenticationManager);
        this.runtimeManager = runtimeManager;
        this.repositoryManager = repositoryManager;
    }
    /**
src/main/java/com/gitblit/servlet/AuthenticationFilter.java
@@ -21,6 +21,7 @@
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
@@ -35,13 +36,10 @@
import org.slf4j.LoggerFactory;
import com.gitblit.Constants;
import com.gitblit.dagger.DaggerFilter;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.models.UserModel;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * The AuthenticationFilter is a servlet filter that preprocesses requests that
@@ -52,7 +50,7 @@
 * @author James Moger
 *
 */
public abstract class AuthenticationFilter extends DaggerFilter {
public abstract class AuthenticationFilter implements Filter {
    protected static final String CHALLENGE = "Basic realm=\"" + Constants.NAME + "\"";
@@ -62,9 +60,16 @@
    protected IAuthenticationManager authenticationManager;
    protected AuthenticationFilter(IAuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }
    @Override
    protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
        this.authenticationManager = dagger.get(IAuthenticationManager.class);
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void destroy() {
    }
    /**
src/main/java/com/gitblit/servlet/BranchGraphServlet.java
@@ -36,7 +36,10 @@
import java.util.TreeSet;
import javax.imageio.ImageIO;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -52,12 +55,9 @@
import com.gitblit.Constants;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * Handles requests for branch graphs
@@ -65,7 +65,8 @@
 * @author James Moger
 *
 */
public class BranchGraphServlet extends DaggerServlet {
@Singleton
public class BranchGraphServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
@@ -82,18 +83,18 @@
    private IRepositoryManager repositoryManager;
    public BranchGraphServlet() {
        super();
    @Inject
    public BranchGraphServlet(
            IStoredSettings settings,
            IRepositoryManager repositoryManager) {
        this.settings = settings;
        this.repositoryManager = repositoryManager;
        strokeCache = new Stroke[4];
        for (int i = 1; i < strokeCache.length; i++) {
            strokeCache[i] = new BasicStroke(i);
        }
    }
    @Override
    protected void inject(ObjectGraph dagger) {
        this.settings = dagger.get(IStoredSettings.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
    }
    /**
src/main/java/com/gitblit/servlet/DownloadZipFilter.java
@@ -15,7 +15,13 @@
 */
package com.gitblit.servlet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
@@ -27,8 +33,18 @@
 * @author James Moger
 *
 */
@Singleton
public class DownloadZipFilter extends AccessRestrictionFilter {
    @Inject
    public DownloadZipFilter(
            IRuntimeManager runtimeManager,
            IAuthenticationManager authenticationManager,
            IRepositoryManager repositoryManager) {
        super(runtimeManager, authenticationManager, repositoryManager);
    }
    /**
     * Extract the repository name from the url.
     *
src/main/java/com/gitblit/servlet/DownloadZipServlet.java
@@ -20,7 +20,10 @@
import java.text.ParseException;
import java.util.Date;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.lib.Repository;
@@ -31,14 +34,11 @@
import com.gitblit.Constants;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.utils.CompressionUtils;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * Streams out a zip file from the specified repository for any tree path at any
@@ -47,7 +47,8 @@
 * @author James Moger
 *
 */
public class DownloadZipServlet extends DaggerServlet {
@Singleton
public class DownloadZipServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
@@ -76,10 +77,10 @@
        }
    }
    @Override
    protected void inject(ObjectGraph dagger) {
        this.settings = dagger.get(IStoredSettings.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
    @Inject
    public DownloadZipServlet(IStoredSettings settings, IRepositoryManager repositoryManager) {
        this.settings = settings;
        this.repositoryManager = repositoryManager;
    }
    /**
src/main/java/com/gitblit/servlet/EnforceAuthenticationFilter.java
@@ -18,6 +18,9 @@
import java.io.IOException;
import java.text.MessageFormat;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
@@ -31,11 +34,8 @@
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerFilter;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.models.UserModel;
import dagger.ObjectGraph;
/**
 * This filter enforces authentication via HTTP Basic Authentication, if the settings indicate so.
@@ -45,7 +45,8 @@
 * @author Laurens Vrijnsen
 *
 */
public class EnforceAuthenticationFilter extends DaggerFilter {
@Singleton
public class EnforceAuthenticationFilter implements Filter {
    protected transient Logger logger = LoggerFactory.getLogger(getClass());
@@ -53,10 +54,21 @@
    private IAuthenticationManager authenticationManager;
    @Inject
    public EnforceAuthenticationFilter(
            IStoredSettings settings,
            IAuthenticationManager authenticationManager) {
        this.settings = settings;
        this.authenticationManager = authenticationManager;
    }
    @Override
    protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
        this.settings = dagger.get(IStoredSettings.class);
        this.authenticationManager = dagger.get(IAuthenticationManager.class);
    public void init(FilterConfig config) {
    }
    @Override
    public void destroy() {
    }
    /*
@@ -86,13 +98,5 @@
            // user is authenticated, or don't care, continue handling
            chain.doFilter(request, response);
        }
    }
    /*
     * @see javax.servlet.Filter#destroy()
     */
    @Override
    public void destroy() {
    }
}
src/main/java/com/gitblit/servlet/FederationServlet.java
@@ -25,6 +25,8 @@
import java.util.Map;
import java.util.Set;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServletResponse;
import com.gitblit.Constants.FederationRequest;
@@ -43,14 +45,13 @@
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;
import dagger.ObjectGraph;
/**
 * Handles federation requests.
 *
 * @author James Moger
 *
 */
@Singleton
public class FederationServlet extends JsonServlet {
    private static final long serialVersionUID = 1L;
@@ -63,12 +64,17 @@
    private IFederationManager federationManager;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.settings = dagger.get(IStoredSettings.class);
        this.userManager = dagger.get(IUserManager.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
        this.federationManager = dagger.get(IFederationManager.class);
    @Inject
    public FederationServlet(
            IStoredSettings settings,
            IUserManager userManager,
            IRepositoryManager repositoryManager,
            IFederationManager federationManager) {
        this.settings = settings;
        this.userManager = userManager;
        this.repositoryManager = repositoryManager;
        this.federationManager = federationManager;
    }
    /**
src/main/java/com/gitblit/servlet/GitFilter.java
@@ -17,7 +17,8 @@
import java.text.MessageFormat;
import javax.servlet.FilterConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import com.gitblit.Constants.AccessRestrictionType;
@@ -25,12 +26,13 @@
import com.gitblit.GitBlitException;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IFederationManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * The GitFilter is an AccessRestrictionFilter which ensures that Git client
@@ -40,6 +42,7 @@
 * @author James Moger
 *
 */
@Singleton
public class GitFilter extends AccessRestrictionFilter {
    protected static final String gitReceivePack = "/git-receive-pack";
@@ -53,11 +56,18 @@
    private IFederationManager federationManager;
    @Override
    protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
        super.inject(dagger, filterConfig);
        this.settings = dagger.get(IStoredSettings.class);
        this.federationManager = dagger.get(IFederationManager.class);
    @Inject
    public GitFilter(
            IStoredSettings settings,
            IRuntimeManager runtimeManager,
            IAuthenticationManager authenticationManager,
            IRepositoryManager repositoryManager,
            IFederationManager federationManager) {
        super(runtimeManager, authenticationManager, repositoryManager);
        this.settings = settings;
        this.federationManager = federationManager;
    }
    /**
src/main/java/com/gitblit/servlet/GitServlet.java
@@ -20,6 +20,8 @@
import java.io.IOException;
import java.util.Enumeration;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
@@ -33,13 +35,10 @@
import org.eclipse.jgit.http.server.GitFilter;
import com.gitblit.dagger.DaggerContext;
import com.gitblit.git.GitblitReceivePackFactory;
import com.gitblit.git.GitblitUploadPackFactory;
import com.gitblit.git.RepositoryResolver;
import com.gitblit.manager.IGitblit;
import dagger.ObjectGraph;
/**
 * The GitServlet provides http/https access to Git repositories.
@@ -48,24 +47,23 @@
 * @author James Moger
 *
 */
@Singleton
public class GitServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private final GitFilter gitFilter;
    public GitServlet() {
    @Inject
    public GitServlet(IGitblit gitblit) {
        gitFilter = new GitFilter();
        gitFilter.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>(gitblit));
        gitFilter.setUploadPackFactory(new GitblitUploadPackFactory<HttpServletRequest>(gitblit));
        gitFilter.setReceivePackFactory(new GitblitReceivePackFactory<HttpServletRequest>(gitblit));
    }
    @Override
    public void init(final ServletConfig config) throws ServletException {
        ServletContext context = config.getServletContext();
        ObjectGraph dagger = (ObjectGraph) context.getAttribute(DaggerContext.INJECTOR_NAME);
        IGitblit gitblit = dagger.get(IGitblit.class);
        gitFilter.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>(gitblit));
        gitFilter.setUploadPackFactory(new GitblitUploadPackFactory<HttpServletRequest>(gitblit));
        gitFilter.setReceivePackFactory(new GitblitReceivePackFactory<HttpServletRequest>(gitblit));
        gitFilter.init(new FilterConfig() {
            @Override
src/main/java/com/gitblit/servlet/GitblitContext.java
@@ -31,14 +31,17 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.Constants;
import com.gitblit.DaggerModule;
import com.gitblit.FileSettings;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.WebXmlSettings;
import com.gitblit.dagger.DaggerContext;
import com.gitblit.extensions.LifeCycleListener;
import com.gitblit.guice.CoreModule;
import com.gitblit.guice.WebModule;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IFederationManager;
import com.gitblit.manager.IGitblit;
@@ -48,27 +51,33 @@
import com.gitblit.manager.IProjectManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.manager.IServicesManager;
import com.gitblit.manager.IUserManager;
import com.gitblit.tickets.ITicketService;
import com.gitblit.transport.ssh.IPublicKeyManager;
import com.gitblit.utils.ContainerUtils;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;
/**
 * This class is the main entry point for the entire webapp.  It is a singleton
 * created manually by Gitblit GO or dynamically by the WAR/Express servlet
 * container.  This class instantiates and starts all managers.  Servlets and
 * filters are instantiated defined in web.xml and instantiated by the servlet
 * container, but those servlets and filters use Dagger to manually inject their
 * dependencies.
 * container.  This class instantiates and starts all managers.
 *
 * Servlets and filters are injected which allows Gitblit to be completely
 * code-driven.
 *
 * @author James Moger
 *
 */
public class GitblitContext extends DaggerContext {
public class GitblitContext extends GuiceServletContextListener {
    private static GitblitContext gitblit;
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    private final List<IManager> managers = new ArrayList<IManager>();
@@ -111,12 +120,16 @@
        return null;
    }
    /**
     * Returns Gitblit's Dagger injection modules.
     */
    @Override
    protected Object [] getModules() {
        return new Object [] { new DaggerModule() };
    protected Injector getInjector() {
        return Guice.createInjector(getModules());
    }
    /**
     * Returns Gitblit's Guice injection modules.
     */
    protected AbstractModule [] getModules() {
        return new AbstractModule [] { new CoreModule(), new WebModule() };
    }
    /**
@@ -127,18 +140,20 @@
     */
    @Override
    public final void contextInitialized(ServletContextEvent contextEvent) {
        super.contextInitialized(contextEvent);
        ServletContext context = contextEvent.getServletContext();
        configureContext(context);
        startCore(context);
    }
    /**
     * Prepare runtime settings and start all manager instances.
     */
    protected void configureContext(ServletContext context) {
        ObjectGraph injector = getInjector(context);
    protected void startCore(ServletContext context) {
        Injector injector = (Injector) context.getAttribute(Injector.class.getName());
        // create the runtime settings object
        IStoredSettings runtimeSettings = injector.get(IStoredSettings.class);
        IStoredSettings runtimeSettings = injector.getInstance(IStoredSettings.class);
        final File baseFolder;
        if (goSettings != null) {
@@ -168,7 +183,7 @@
        // Manually configure IRuntimeManager
        logManager(IRuntimeManager.class);
        IRuntimeManager runtime = injector.get(IRuntimeManager.class);
        IRuntimeManager runtime = injector.getInstance(IRuntimeManager.class);
        runtime.setBaseFolder(baseFolder);
        runtime.getStatus().isGO = goSettings != null;
        runtime.getStatus().servletContainer = context.getServerInfo();
@@ -186,7 +201,9 @@
        startManager(injector, IRepositoryManager.class);
        startManager(injector, IProjectManager.class);
        startManager(injector, IFederationManager.class);
        startManager(injector, ITicketService.class);
        startManager(injector, IGitblit.class);
        startManager(injector, IServicesManager.class);
        // start the plugin manager last so that plugins can depend on
        // deterministic access to all other managers in their start() methods
@@ -196,7 +213,7 @@
        logger.info("All managers started.");
        logger.info("");
        IPluginManager pluginManager = injector.get(IPluginManager.class);
        IPluginManager pluginManager = injector.getInstance(IPluginManager.class);
        for (LifeCycleListener listener : pluginManager.getExtensions(LifeCycleListener.class)) {
            try {
                listener.onStartup();
@@ -218,12 +235,12 @@
        return null;
    }
    protected <X extends IManager> X loadManager(ObjectGraph injector, Class<X> clazz) {
        X x = injector.get(clazz);
    protected <X extends IManager> X loadManager(Injector injector, Class<X> clazz) {
        X x = injector.getInstance(clazz);
        return x;
    }
    protected <X extends IManager> X startManager(ObjectGraph injector, Class<X> clazz) {
    protected <X extends IManager> X startManager(Injector injector, Class<X> clazz) {
        X x = loadManager(injector, clazz);
        logManager(clazz);
        x.start();
@@ -236,11 +253,17 @@
        logger.info("----[{}]----", clazz.getName());
    }
    @Override
    public final void contextDestroyed(ServletContextEvent contextEvent) {
        super.contextDestroyed(contextEvent);
        ServletContext context = contextEvent.getServletContext();
        destroyContext(context);
    }
    /**
     * Gitblit is being shutdown either because the servlet container is
     * shutting down or because the servlet container is re-deploying Gitblit.
     */
    @Override
    protected void destroyContext(ServletContext context) {
        logger.info("Gitblit context destroyed by servlet container.");
src/main/java/com/gitblit/servlet/JsonServlet.java
@@ -21,6 +21,7 @@
import java.text.MessageFormat;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -28,7 +29,6 @@
import org.slf4j.LoggerFactory;
import com.gitblit.Constants;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.utils.JsonUtils;
import com.gitblit.utils.StringUtils;
@@ -38,7 +38,7 @@
 * @author James Moger
 *
 */
public abstract class JsonServlet extends DaggerServlet {
public abstract class JsonServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
src/main/java/com/gitblit/servlet/LogoServlet.java
@@ -21,16 +21,16 @@
import java.io.InputStream;
import java.io.OutputStream;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IRuntimeManager;
import dagger.ObjectGraph;
/**
 * Handles requests for logo.png
@@ -38,7 +38,8 @@
 * @author James Moger
 *
 */
public class LogoServlet extends DaggerServlet {
@Singleton
public class LogoServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
@@ -46,9 +47,9 @@
    private IRuntimeManager runtimeManager;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.runtimeManager = dagger.get(IRuntimeManager.class);
    @Inject
    public LogoServlet(IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
    }
    @Override
src/main/java/com/gitblit/servlet/PagesFilter.java
@@ -15,6 +15,13 @@
 */
package com.gitblit.servlet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
/**
 * The PagesFilter is an AccessRestrictionFilter which ensures the gh-pages
@@ -23,7 +30,17 @@
 * @author James Moger
 *
 */
@Singleton
public class PagesFilter extends RawFilter {
    @Inject
    public PagesFilter(
            IRuntimeManager runtimeManager,
            IAuthenticationManager authenticationManager,
            IRepositoryManager repositoryManager) {
        super(runtimeManager, authenticationManager, repositoryManager);
    }
}
src/main/java/com/gitblit/servlet/PagesServlet.java
@@ -15,10 +15,14 @@
 */
package com.gitblit.servlet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.gitblit.Constants;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
/**
 * Serves the content of a gh-pages branch.
@@ -26,6 +30,7 @@
 * @author James Moger
 *
 */
@Singleton
public class PagesServlet extends RawServlet {
    private static final long serialVersionUID = 1L;
@@ -46,6 +51,14 @@
        return baseURL + Constants.PAGES + repository + "/" + (path == null ? "" : ("/" + path));
    }
    @Inject
    public PagesServlet(
            IRuntimeManager runtimeManager,
            IRepositoryManager repositoryManager) {
        super(runtimeManager, repositoryManager);
    }
    @Override
    protected String getBranch(String repository, HttpServletRequest request) {
        return "gh-pages";
src/main/java/com/gitblit/servlet/ProxyFilter.java
@@ -16,9 +16,13 @@
package com.gitblit.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
@@ -27,12 +31,9 @@
import ro.fortsoft.pf4j.PluginWrapper;
import com.gitblit.dagger.DaggerFilter;
import com.gitblit.extensions.HttpRequestFilter;
import com.gitblit.manager.IPluginManager;
import com.gitblit.manager.IRuntimeManager;
import dagger.ObjectGraph;
/**
 * A request filter than allows registered extension request filters to access
@@ -41,15 +42,29 @@
 * @author David Ostrovsky
 * @since 1.6.0
 */
public class ProxyFilter extends DaggerFilter {
    private List<HttpRequestFilter> filters;
@Singleton
public class ProxyFilter implements Filter {
    private final IRuntimeManager runtimeManager;
    private final IPluginManager pluginManager;
    private final List<HttpRequestFilter> filters;
    @Inject
    public ProxyFilter(
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager) {
        this.runtimeManager = runtimeManager;
        this.pluginManager = pluginManager;
        this.filters = new ArrayList<>();
    }
    @Override
    protected void inject(ObjectGraph dagger, FilterConfig filterConfig) throws ServletException {
        IRuntimeManager runtimeManager = dagger.get(IRuntimeManager.class);
        IPluginManager pluginManager = dagger.get(IPluginManager.class);
    public void init(FilterConfig filterConfig) throws ServletException {
        filters = pluginManager.getExtensions(HttpRequestFilter.class);
        filters.addAll(pluginManager.getExtensions(HttpRequestFilter.class));
        for (HttpRequestFilter f : filters) {
            // wrap the filter config for Gitblit settings retrieval
            PluginWrapper pluginWrapper = pluginManager.whichPlugin(f.getClass());
src/main/java/com/gitblit/servlet/PtServlet.java
@@ -21,7 +21,10 @@
import java.io.InputStream;
import java.io.OutputStream;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -34,10 +37,7 @@
import org.apache.wicket.util.io.ByteArrayOutputStream;
import org.eclipse.jgit.lib.FileMode;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IRuntimeManager;
import dagger.ObjectGraph;
/**
 * Handles requests for the Barnum pt (patchset tool).
@@ -47,7 +47,8 @@
 * @author James Moger
 *
 */
public class PtServlet extends DaggerServlet {
@Singleton
public class PtServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
@@ -55,9 +56,9 @@
    private IRuntimeManager runtimeManager;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.runtimeManager = dagger.get(IRuntimeManager.class);
    @Inject
    public PtServlet(IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
    }
    @Override
src/main/java/com/gitblit/servlet/RawFilter.java
@@ -15,9 +15,15 @@
 */
package com.gitblit.servlet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Repository;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
@@ -28,8 +34,18 @@
 * @author James Moger
 *
 */
@Singleton
public class RawFilter extends AccessRestrictionFilter {
    @Inject
    public RawFilter(
            IRuntimeManager runtimeManager,
            IAuthenticationManager authenticationManager,
            IRepositoryManager repositoryManager) {
        super(runtimeManager, authenticationManager, repositoryManager);
    }
    /**
     * Extract the repository name from the url.
     *
src/main/java/com/gitblit/servlet/RawServlet.java
@@ -28,8 +28,11 @@
import java.util.Map;
import java.util.TreeMap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -48,7 +51,6 @@
import com.gitblit.Constants;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.PathModel;
@@ -57,28 +59,30 @@
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * Serves the content of a branch.
 *
 * @author James Moger
 *
 */
public class RawServlet extends DaggerServlet {
@Singleton
public class RawServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private transient Logger logger = LoggerFactory.getLogger(RawServlet.class);
    private IRuntimeManager runtimeManager;
    private final IRuntimeManager runtimeManager;
    private IRepositoryManager repositoryManager;
    private final IRepositoryManager repositoryManager;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.runtimeManager = dagger.get(IRuntimeManager.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
    @Inject
    public RawServlet(
            IRuntimeManager runtimeManager,
            IRepositoryManager repositoryManager) {
        this.runtimeManager = runtimeManager;
        this.repositoryManager = repositoryManager;
    }
    /**
src/main/java/com/gitblit/servlet/RobotsTxtServlet.java
@@ -18,16 +18,16 @@
import java.io.File;
import java.io.IOException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.utils.FileUtils;
import dagger.ObjectGraph;
/**
 * Handles requests for robots.txt
@@ -35,15 +35,16 @@
 * @author James Moger
 *
 */
public class RobotsTxtServlet extends DaggerServlet {
@Singleton
public class RobotsTxtServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private IRuntimeManager runtimeManager;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.runtimeManager = dagger.get(IRuntimeManager.class);
    @Inject
    public RobotsTxtServlet(IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
    }
    @Override
src/main/java/com/gitblit/servlet/RpcFilter.java
@@ -18,8 +18,9 @@
import java.io.IOException;
import java.text.MessageFormat;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -29,10 +30,9 @@
import com.gitblit.Constants.RpcRequest;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.UserModel;
import dagger.ObjectGraph;
/**
 * The RpcFilter is a servlet filter that secures the RpcServlet.
@@ -47,17 +47,23 @@
 * @author James Moger
 *
 */
@Singleton
public class RpcFilter extends AuthenticationFilter {
    private IStoredSettings settings;
    private IRuntimeManager runtimeManager;
    @Override
    protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
        super.inject(dagger, filterConfig);
        this.settings = dagger.get(IStoredSettings.class);
        this.runtimeManager = dagger.get(IRuntimeManager.class);
    @Inject
    public RpcFilter(
            IStoredSettings settings,
            IRuntimeManager runtimeManager,
            IAuthenticationManager authenticationManager) {
        super(authenticationManager);
        this.settings = settings;
        this.runtimeManager = runtimeManager;
    }
    /**
src/main/java/com/gitblit/servlet/RpcServlet.java
@@ -23,6 +23,8 @@
import java.util.List;
import java.util.Map;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -47,13 +49,12 @@
import com.gitblit.utils.RpcUtils;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * Handles remote procedure calls.
 *
 * @author James Moger
 */
@Singleton
public class RpcServlet extends JsonServlet {
    private static final long serialVersionUID = 1L;
@@ -64,10 +65,10 @@
    private IGitblit gitblit;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.settings = dagger.get(IStoredSettings.class);
        this.gitblit = dagger.get(IGitblit.class);
    @Inject
    public RpcServlet(IStoredSettings settings, IGitblit gitblit) {
        this.settings = settings;
        this.gitblit = gitblit;
    }
    /**
src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java
@@ -19,13 +19,15 @@
import java.net.URL;
import java.text.MessageFormat;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IUserManager;
@@ -33,15 +35,14 @@
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 * Handles requests for Sparkleshare Invites
 *
 * @author James Moger
 *
 */
public class SparkleShareInviteServlet extends DaggerServlet {
@Singleton
public class SparkleShareInviteServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
@@ -53,12 +54,17 @@
    private IRepositoryManager repositoryManager;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.settings = dagger.get(IStoredSettings.class);
        this.userManager = dagger.get(IUserManager.class);
        this.authenticationManager = dagger.get(IAuthenticationManager.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
    @Inject
    public SparkleShareInviteServlet(
            IStoredSettings settings,
            IUserManager userManager,
            IAuthenticationManager authenticationManager,
            IRepositoryManager repositoryManager) {
        this.settings = settings;
        this.userManager = userManager;
        this.authenticationManager = authenticationManager;
        this.repositoryManager = repositoryManager;
    }
    @Override
src/main/java/com/gitblit/servlet/SyndicationFilter.java
@@ -18,8 +18,9 @@
import java.io.IOException;
import java.text.MessageFormat;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -27,14 +28,13 @@
import javax.servlet.http.HttpServletResponse;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IProjectManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import dagger.ObjectGraph;
/**
 * The SyndicationFilter is an AuthenticationFilter which ensures that feed
@@ -44,18 +44,24 @@
 * @author James Moger
 *
 */
@Singleton
public class SyndicationFilter extends AuthenticationFilter {
    private IRuntimeManager runtimeManager;
    private IRepositoryManager repositoryManager;
    private IProjectManager projectManager;
    @Override
    protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
        super.inject(dagger, filterConfig);
        this.runtimeManager = dagger.get(IRuntimeManager.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
        this.projectManager = dagger.get(IProjectManager.class);
    @Inject
    public SyndicationFilter(
            IRuntimeManager runtimeManager,
            IAuthenticationManager authenticationManager,
            IRepositoryManager repositoryManager,
            IProjectManager projectManager) {
        super(authenticationManager);
        this.runtimeManager = runtimeManager;
        this.repositoryManager = repositoryManager;
        this.projectManager = projectManager;
    }
    /**
src/main/java/com/gitblit/servlet/SyndicationServlet.java
@@ -22,6 +22,10 @@
import java.util.List;
import java.util.Map;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServlet;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -31,7 +35,6 @@
import com.gitblit.Constants;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerServlet;
import com.gitblit.manager.IProjectManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.models.FeedEntryModel;
@@ -46,8 +49,6 @@
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.SyndicationUtils;
import dagger.ObjectGraph;
/**
 * SyndicationServlet generates RSS 2.0 feeds and feed links.
 *
@@ -56,7 +57,8 @@
 * @author James Moger
 *
 */
public class SyndicationServlet extends DaggerServlet {
@Singleton
public class SyndicationServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
@@ -68,11 +70,15 @@
    private IProjectManager projectManager;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.settings = dagger.get(IStoredSettings.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
        this.projectManager = dagger.get(IProjectManager.class);
    @Inject
    public SyndicationServlet(
            IStoredSettings settings,
            IRepositoryManager repositoryManager,
            IProjectManager projectManager) {
        this.settings = settings;
        this.repositoryManager = repositoryManager;
        this.projectManager = projectManager;
    }
    /**
src/main/java/com/gitblit/tickets/BranchTicketService.java
@@ -72,6 +72,8 @@
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * Implementation of a ticket service based on an orphan branch.  All tickets
@@ -81,6 +83,7 @@
 * @author James Moger
 *
 */
@Singleton
public class BranchTicketService extends ITicketService implements RefsChangedListener {
    public static final String BRANCH = "refs/meta/gitblit/tickets";
@@ -91,6 +94,7 @@
    private final Map<String, AtomicLong> lastAssignedId;
    @Inject
    public BranchTicketService(
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
@@ -112,6 +116,7 @@
    @Override
    public BranchTicketService start() {
        log.info("{} started", getClass().getSimpleName());
        return this;
    }
src/main/java/com/gitblit/tickets/FileTicketService.java
@@ -42,6 +42,8 @@
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.FileUtils;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * Implementation of a ticket service based on a directory within the repository.
@@ -51,6 +53,7 @@
 * @author James Moger
 *
 */
@Singleton
public class FileTicketService extends ITicketService {
    private static final String JOURNAL = "journal.json";
@@ -59,6 +62,7 @@
    private final Map<String, AtomicLong> lastAssignedId;
    @Inject
    public FileTicketService(
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
@@ -77,6 +81,7 @@
    @Override
    public FileTicketService start() {
        log.info("{} started", getClass().getSimpleName());
        return this;
    }
src/main/java/com/gitblit/tickets/ITicketService.java
@@ -36,6 +36,7 @@
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.extensions.TicketHook;
import com.gitblit.manager.IManager;
import com.gitblit.manager.INotificationManager;
import com.gitblit.manager.IPluginManager;
import com.gitblit.manager.IRepositoryManager;
@@ -63,7 +64,7 @@
 * @author James Moger
 *
 */
public abstract class ITicketService {
public abstract class ITicketService implements IManager {
    public static final String SETTING_UPDATE_DIFFSTATS = "migration.updateDiffstats";
@@ -176,12 +177,14 @@
     * Start the service.
     * @since 1.4.0
     */
    @Override
    public abstract ITicketService start();
    /**
     * Stop the service.
     * @since 1.4.0
     */
    @Override
    public final ITicketService stop() {
        indexer.close();
        ticketsCache.invalidateAll();
src/main/java/com/gitblit/tickets/NullTicketService.java
@@ -28,6 +28,8 @@
import com.gitblit.models.TicketModel;
import com.gitblit.models.TicketModel.Attachment;
import com.gitblit.models.TicketModel.Change;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * Implementation of a ticket service that rejects everything.
@@ -35,8 +37,10 @@
 * @author James Moger
 *
 */
@Singleton
public class NullTicketService extends ITicketService {
    @Inject
    public NullTicketService(
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
@@ -58,6 +62,7 @@
    @Override
    public NullTicketService start() {
        log.info("{} started", getClass().getSimpleName());
        return this;
    }
src/main/java/com/gitblit/tickets/RedisTicketService.java
@@ -43,6 +43,8 @@
import com.gitblit.models.TicketModel.Change;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.StringUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
 * Implementation of a ticket service based on a Redis key-value store.  All
@@ -53,6 +55,7 @@
 * @author James Moger
 *
 */
@Singleton
public class RedisTicketService extends ITicketService {
    private final JedisPool pool;
@@ -61,6 +64,7 @@
        journal, ticket, counter
    }
    @Inject
    public RedisTicketService(
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
@@ -80,6 +84,10 @@
    @Override
    public RedisTicketService start() {
        log.info("{} started", getClass().getSimpleName());
        if (!isReady()) {
            log.warn("{} is not ready!", getClass().getSimpleName());
        }
        return this;
    }
src/main/java/com/gitblit/transport/ssh/FileKeyManager.java
@@ -29,6 +29,7 @@
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.io.Files;
import com.google.inject.Inject;
/**
 * Manages public keys on the filesystem.
@@ -42,6 +43,7 @@
    protected final Map<File, Long> lastModifieds;
    @Inject
    public FileKeyManager(IRuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
        this.lastModifieds = new ConcurrentHashMap<File, Long>();
src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java
@@ -20,6 +20,8 @@
import java.util.List;
import java.util.Map;
import com.google.inject.Inject;
/**
 * Memory public key manager.
 *
@@ -30,6 +32,7 @@
    final Map<String, List<SshKey>> keys;
    @Inject
    public MemoryKeyManager() {
        keys = new HashMap<String, List<SshKey>>();
    }
src/main/java/com/gitblit/transport/ssh/NullKeyManager.java
@@ -17,6 +17,8 @@
import java.util.List;
import com.google.inject.Inject;
/**
 * Rejects all public key management requests.
 *
@@ -25,6 +27,7 @@
 */
public class NullKeyManager extends IPublicKeyManager {
    @Inject
    public NullKeyManager() {
    }
src/main/java/com/gitblit/wicket/GitBlitWebApp.java
@@ -43,6 +43,7 @@
import com.gitblit.manager.IProjectManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.manager.IServicesManager;
import com.gitblit.manager.IUserManager;
import com.gitblit.tickets.ITicketService;
import com.gitblit.transport.ssh.IPublicKeyManager;
@@ -89,7 +90,11 @@
import com.gitblit.wicket.pages.TreePage;
import com.gitblit.wicket.pages.UserPage;
import com.gitblit.wicket.pages.UsersPage;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@Singleton
public class GitBlitWebApp extends WebApplication implements GitblitWicketApp {
    private final Class<? extends WebPage> homePageClass = MyDashboardPage.class;
@@ -97,6 +102,10 @@
    private final Class<? extends WebPage> newRepositoryPageClass = NewRepositoryPage.class;
    private final Map<String, CacheControl> cacheablePages = new HashMap<String, CacheControl>();
    private final Provider<IPublicKeyManager> publicKeyManagerProvider;
    private final Provider<ITicketService> ticketServiceProvider;
    private final IStoredSettings settings;
@@ -110,8 +119,6 @@
    private final IAuthenticationManager authenticationManager;
    private final IPublicKeyManager publicKeyManager;
    private final IRepositoryManager repositoryManager;
    private final IProjectManager projectManager;
@@ -120,30 +127,37 @@
    private final IGitblit gitblit;
    private final IServicesManager services;
    @Inject
    public GitBlitWebApp(
            Provider<IPublicKeyManager> publicKeyManagerProvider,
            Provider<ITicketService> ticketServiceProvider,
            IRuntimeManager runtimeManager,
            IPluginManager pluginManager,
            INotificationManager notificationManager,
            IUserManager userManager,
            IAuthenticationManager authenticationManager,
            IPublicKeyManager publicKeyManager,
            IRepositoryManager repositoryManager,
            IProjectManager projectManager,
            IFederationManager federationManager,
            IGitblit gitblit) {
            IGitblit gitblit,
            IServicesManager services) {
        super();
        this.publicKeyManagerProvider = publicKeyManagerProvider;
        this.ticketServiceProvider = ticketServiceProvider;
        this.settings = runtimeManager.getSettings();
        this.runtimeManager = runtimeManager;
        this.pluginManager = pluginManager;
        this.notificationManager = notificationManager;
        this.userManager = userManager;
        this.authenticationManager = authenticationManager;
        this.publicKeyManager = publicKeyManager;
        this.repositoryManager = repositoryManager;
        this.projectManager = projectManager;
        this.federationManager = federationManager;
        this.gitblit = gitblit;
        this.services = services;
    }
    @Override
@@ -380,7 +394,7 @@
     */
    @Override
    public IPublicKeyManager keys() {
        return publicKeyManager;
        return publicKeyManagerProvider.get();
    }
    /* (non-Javadoc)
@@ -416,11 +430,19 @@
    }
    /* (non-Javadoc)
     * @see com.gitblit.wicket.Webapp#services()
     */
    @Override
    public IServicesManager services() {
        return services;
    }
    /* (non-Javadoc)
     * @see com.gitblit.wicket.Webapp#tickets()
     */
    @Override
    public ITicketService tickets() {
        return gitblit.getTicketService();
        return ticketServiceProvider.get();
    }
    /* (non-Javadoc)
src/main/java/com/gitblit/wicket/GitblitWicketApp.java
@@ -14,6 +14,7 @@
import com.gitblit.manager.IProjectManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.manager.IServicesManager;
import com.gitblit.manager.IUserManager;
import com.gitblit.tickets.ITicketService;
import com.gitblit.transport.ssh.IPublicKeyManager;
@@ -65,6 +66,8 @@
    public abstract IGitblit gitblit();
    public abstract IServicesManager services();
    public abstract ITicketService tickets();
    public abstract TimeZone getTimezone();
src/main/java/com/gitblit/wicket/GitblitWicketFilter.java
@@ -17,6 +17,8 @@
import java.util.Date;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.protocol.http.IWebApplicationFactory;
@@ -28,7 +30,6 @@
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.dagger.DaggerWicketFilter;
import com.gitblit.manager.IProjectManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
@@ -36,8 +37,6 @@
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import dagger.ObjectGraph;
/**
 *
@@ -47,7 +46,8 @@
 * @author James Moger
 *
 */
public class GitblitWicketFilter extends DaggerWicketFilter {
@Singleton
public class GitblitWicketFilter extends WicketFilter {
    private IStoredSettings settings;
@@ -59,13 +59,19 @@
    private GitBlitWebApp webapp;
    @Override
    protected void inject(ObjectGraph dagger) {
        this.settings = dagger.get(IStoredSettings.class);
        this.runtimeManager = dagger.get(IRuntimeManager.class);
        this.repositoryManager = dagger.get(IRepositoryManager.class);
        this.projectManager = dagger.get(IProjectManager.class);
        this.webapp = dagger.get(GitBlitWebApp.class);
    @Inject
    public GitblitWicketFilter(
            IStoredSettings settings,
            IRuntimeManager runtimeManager,
            IRepositoryManager repositoryManager,
            IProjectManager projectManager,
            GitBlitWebApp webapp) {
        this.settings = settings;
        this.runtimeManager = runtimeManager;
        this.repositoryManager = repositoryManager;
        this.projectManager = projectManager;
        this.webapp = webapp;
    }
    @Override
src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
@@ -55,7 +55,7 @@
        }
        HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();
        List<RepositoryUrl> repositoryUrls = app().gitblit().getRepositoryUrls(req, user, repository);
        List<RepositoryUrl> repositoryUrls = app().services().getRepositoryUrls(req, user, repository);
        RepositoryUrl primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0);
        String url = primaryUrl != null ? primaryUrl.url : "";
src/main/java/com/gitblit/wicket/pages/TicketPage.java
@@ -1505,7 +1505,7 @@
     */
    protected RepositoryUrl getRepositoryUrl(UserModel user, RepositoryModel repository) {
        HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();
        List<RepositoryUrl> urls = app().gitblit().getRepositoryUrls(req, user, repository);
        List<RepositoryUrl> urls = app().services().getRepositoryUrls(req, user, repository);
        if (ArrayUtils.isEmpty(urls)) {
            return null;
        }
src/main/java/com/gitblit/wicket/pages/UserPage.java
@@ -104,7 +104,7 @@
        if (isMyProfile) {
            addPreferences(user);
            if (app().gitblit().isServingSSH()) {
            if (app().services().isServingSSH()) {
                // show the SSH key management tab
                addSshKeys(user);
            } else {
@@ -248,14 +248,14 @@
                emailMeOnMyTicketChanges).setVisible(app().notifier().isSendingMail()));
        List<Transport> availableTransports = new ArrayList<>();
        if (app().gitblit().isServingSSH()) {
        if (app().services().isServingSSH()) {
            availableTransports.add(Transport.SSH);
        }
        if (app().gitblit().isServingHTTP()) {
        if (app().services().isServingHTTP()) {
            availableTransports.add(Transport.HTTPS);
            availableTransports.add(Transport.HTTP);
        }
        if (app().gitblit().isServingGIT()) {
        if (app().services().isServingGIT()) {
            availableTransports.add(Transport.GIT);
        }
src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java
@@ -80,7 +80,7 @@
        HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();
        List<RepositoryUrl> repositoryUrls = app().gitblit().getRepositoryUrls(req, user, repository);
        List<RepositoryUrl> repositoryUrls = app().services().getRepositoryUrls(req, user, repository);
        // grab primary url from the top of the list
        primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0);
@@ -165,7 +165,7 @@
        if (repository.isMirror) {
            urlPanel.add(WicketUtils.newImage("accessRestrictionIcon", "mirror_16x16.png",
                    getString("gb.isMirror")));
        } else if (app().gitblit().isServingRepositories()) {
        } else if (app().services().isServingRepositories()) {
            switch (repository.accessRestriction) {
            case NONE:
                urlPanel.add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));
src/site/design.mkd
@@ -57,6 +57,7 @@
- [jedis](https://github.com/xetorthio/jedis) (MIT)
- [Mina SSHD](https://mina.apache.org) (Apache 2.0)
- [pf4j](https://github.com/decebals/pf4j) (Apache 2.0)
- [google-guice](https://code.google.com/p/google-guice) (Apache 2.0)
### Other Build Dependencies
- [Fancybox image viewer](http://fancybox.net) (MIT and GPL dual-licensed)
src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java
@@ -28,6 +28,7 @@
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
import com.gitblit.models.SettingModel;
import com.google.inject.Injector;
public class MockRuntimeManager implements IRuntimeManager {
@@ -57,6 +58,11 @@
    }
    @Override
    public Injector getInjector() {
        return null;
    }
    @Override
    public void setBaseFolder(File folder) {
        this.baseFolder = folder;
    }
@@ -74,26 +80,6 @@
    @Override
    public Locale getLocale() {
        return Locale.getDefault();
    }
    @Override
    public boolean isServingRepositories() {
        return true;
    }
    @Override
    public boolean isServingHTTP() {
        return true;
    }
    @Override
    public boolean isServingGIT() {
        return true;
    }
    @Override
    public boolean isServingSSH() {
        return true;
    }
    @Override