Browse Source

Initial import of Git:Blit.

Change-Id: Ifce000c85c8947c3a768e782c841e41a8953d314
tags/v0.5.0
James Moger 13 years ago
commit
5fe7df81eb
100 changed files with 4869 additions and 0 deletions
  1. 19
    0
      .classpath
  2. 6
    0
      .gitignore
  3. 17
    0
      .project
  4. 92
    0
      build.xml
  5. 1
    0
      gitblit.cmd
  6. 96
    0
      gitblit.properties
  7. 2
    0
      makekeystore.cmd
  8. 12
    0
      makepassword.cmd
  9. 11
    0
      makerepository.cmd
  10. BIN
      resources/arrow_down.png
  11. BIN
      resources/arrow_off.png
  12. BIN
      resources/arrow_up.png
  13. BIN
      resources/git-favicon.png
  14. 56
    0
      resources/gitblit.css
  15. BIN
      resources/gitblt-logo.png
  16. BIN
      resources/gitblt.png
  17. BIN
      resources/gitblt2.png
  18. BIN
      resources/gitblt3.png
  19. BIN
      resources/gitblt_25.png
  20. 604
    0
      resources/gitweb.css
  21. 2
    0
      resources/prettify/lang-apollo.js
  22. 2
    0
      resources/prettify/lang-css.js
  23. 2
    0
      resources/prettify/lang-hs.js
  24. 2
    0
      resources/prettify/lang-lisp.js
  25. 2
    0
      resources/prettify/lang-lua.js
  26. 2
    0
      resources/prettify/lang-ml.js
  27. 1
    0
      resources/prettify/lang-proto.js
  28. 2
    0
      resources/prettify/lang-scala.js
  29. 2
    0
      resources/prettify/lang-sql.js
  30. 2
    0
      resources/prettify/lang-vb.js
  31. 3
    0
      resources/prettify/lang-vhdl.js
  32. 2
    0
      resources/prettify/lang-wiki.js
  33. 2
    0
      resources/prettify/lang-yaml.js
  34. 1
    0
      resources/prettify/prettify.css
  35. 33
    0
      resources/prettify/prettify.js
  36. BIN
      service/JavaService.exe
  37. BIN
      service/JavaService64.exe
  38. 1
    0
      service/UninstallService.bat
  39. 1
    0
      service/UninstallService64.bat
  40. 2
    0
      service/installService.bat
  41. 2
    0
      service/installService64.bat
  42. 168
    0
      src/com/gitblit/Build.java
  43. 12
    0
      src/com/gitblit/Constants.java
  44. 393
    0
      src/com/gitblit/GitBlitServer.java
  45. 117
    0
      src/com/gitblit/Launcher.java
  46. 51
    0
      src/com/gitblit/MakeRepository.java
  47. 130
    0
      src/com/gitblit/StoredSettings.java
  48. 71
    0
      src/com/gitblit/tests/JGitUtilsTest.java
  49. 82
    0
      src/com/gitblit/utils/ByteFormat.java
  50. 430
    0
      src/com/gitblit/utils/JGitUtils.java
  51. 119
    0
      src/com/gitblit/utils/Utils.java
  52. 69
    0
      src/com/gitblit/wicket/BasePage.java
  53. 143
    0
      src/com/gitblit/wicket/GitBlitWebApp.java
  54. 74
    0
      src/com/gitblit/wicket/GitBlitWebSession.java
  55. 6
    0
      src/com/gitblit/wicket/LinkPanel.html
  56. 44
    0
      src/com/gitblit/wicket/LinkPanel.java
  57. 118
    0
      src/com/gitblit/wicket/RepositoryPage.java
  58. 11
    0
      src/com/gitblit/wicket/SecuredPage.java
  59. 35
    0
      src/com/gitblit/wicket/WicketUtils.java
  60. 45
    0
      src/com/gitblit/wicket/models/PathModel.java
  61. 54
    0
      src/com/gitblit/wicket/models/RefModel.java
  62. 20
    0
      src/com/gitblit/wicket/models/RepositoryModel.java
  63. 31
    0
      src/com/gitblit/wicket/pages/BlobPage.html
  64. 94
    0
      src/com/gitblit/wicket/pages/BlobPage.java
  65. 51
    0
      src/com/gitblit/wicket/pages/CommitPage.html
  66. 106
    0
      src/com/gitblit/wicket/pages/CommitPage.java
  67. 26
    0
      src/com/gitblit/wicket/pages/HeadsPage.html
  68. 63
    0
      src/com/gitblit/wicket/pages/HeadsPage.java
  69. 33
    0
      src/com/gitblit/wicket/pages/LogPage.html
  70. 69
    0
      src/com/gitblit/wicket/pages/LogPage.java
  71. 29
    0
      src/com/gitblit/wicket/pages/RepositoriesPage.html
  72. 151
    0
      src/com/gitblit/wicket/pages/RepositoriesPage.java
  73. 31
    0
      src/com/gitblit/wicket/pages/ShortLogPage.html
  74. 76
    0
      src/com/gitblit/wicket/pages/ShortLogPage.java
  75. 76
    0
      src/com/gitblit/wicket/pages/SummaryPage.html
  76. 149
    0
      src/com/gitblit/wicket/pages/SummaryPage.java
  77. 28
    0
      src/com/gitblit/wicket/pages/TagPage.html
  78. 36
    0
      src/com/gitblit/wicket/pages/TagPage.java
  79. 30
    0
      src/com/gitblit/wicket/pages/TagsPage.html
  80. 64
    0
      src/com/gitblit/wicket/pages/TagsPage.java
  81. 35
    0
      src/com/gitblit/wicket/pages/TreePage.html
  82. 89
    0
      src/com/gitblit/wicket/pages/TreePage.java
  83. 8
    0
      src/com/gitblit/wicket/panels/HeadLinksPanel.html
  84. 23
    0
      src/com/gitblit/wicket/panels/HeadLinksPanel.java
  85. 10
    0
      src/com/gitblit/wicket/panels/PageFooter.html
  86. 28
    0
      src/com/gitblit/wicket/panels/PageFooter.java
  87. 15
    0
      src/com/gitblit/wicket/panels/PageHeader.html
  88. 41
    0
      src/com/gitblit/wicket/panels/PageHeader.java
  89. 9
    0
      src/com/gitblit/wicket/panels/PageLinksPanel.html
  90. 61
    0
      src/com/gitblit/wicket/panels/PageLinksPanel.java
  91. 11
    0
      src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.html
  92. 79
    0
      src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.java
  93. 8
    0
      src/com/gitblit/wicket/panels/PathLinksPanel.html
  94. 22
    0
      src/com/gitblit/wicket/panels/PathLinksPanel.java
  95. 8
    0
      src/com/gitblit/wicket/panels/RefsPanel.html
  96. 66
    0
      src/com/gitblit/wicket/panels/RefsPanel.java
  97. 8
    0
      src/com/gitblit/wicket/panels/ShortLogLinksPanel.html
  98. 23
    0
      src/com/gitblit/wicket/panels/ShortLogLinksPanel.java
  99. 8
    0
      src/com/gitblit/wicket/panels/TagLinksPanel.html
  100. 0
    0
      src/com/gitblit/wicket/panels/TagLinksPanel.java

+ 19
- 0
.classpath View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="lib/jgit-0.11.3.jar" sourcepath="/org.eclipse.jgit"/>
<classpathentry kind="lib" path="lib/jgit-http-0.11.3.jar" sourcepath="/org.eclipse.jgit.http.server"/>
<classpathentry kind="lib" path="ext/log4j-1.2.16.jar"/>
<classpathentry kind="lib" path="ext/servlet-api-2.5.jar"/>
<classpathentry kind="lib" path="ext/slf4j-api-1.6.1.jar"/>
<classpathentry kind="lib" path="ext/slf4j-log4j12-1.6.1.jar"/>
<classpathentry kind="lib" path="ext/jetty-all-7.2.2.v20101205.jar"/>
<classpathentry kind="lib" path="ext/jcommander-1.17.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="lib" path="ext/wicket-1.4.17.jar"/>
<classpathentry kind="lib" path="ext/wicket-auth-roles-1.4.17.jar"/>
<classpathentry kind="lib" path="ext/wicket-extensions-1.4.17.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

+ 6
- 0
.gitignore View File

@@ -0,0 +1,6 @@
/temp
/lib
/ext
/build
/keystore
/gitblit.zip

+ 17
- 0
.project View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>gitblit</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

+ 92
- 0
build.xml View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="gitblit" default="main" basedir=".">
<!-- Project Properties -->
<property name="project.jar" value="gitblit.jar" />
<property name="project.mainclass" value="com.gitblit.Launcher" />
<property name="distribution.zipfile" value="gitblit.zip" />
<property name="project.build.dir" value="${basedir}/build" />
<target name="main">
<!-- Compile the build tool and execute it.
This downloads missing compile-time dependencies from Maven. -->
<delete dir="${project.build.dir}" />
<mkdir dir="${project.build.dir}" />
<javac srcdir="${basedir}/src" destdir="${project.build.dir}">
<include name="com/gitblit/Build.java" />
</javac>
<java classpath="${project.build.dir}" classname="com.gitblit.Build" />
<!-- Compile Project -->
<path id="master-classpath">
<fileset dir="${basedir}/lib">
<include name="*.jar" />
</fileset>
<fileset dir="${basedir}/ext">
<include name="*.jar" />
</fileset>
</path>
<javac destdir="${project.build.dir}">
<src path="${basedir}/src" />
<classpath refid="master-classpath" />
</javac>
<copy todir="${project.build.dir}">
<fileset dir="${basedir}/src" excludes="**/*.java,**/thumbs.db" />
<fileset dir="${basedir}/resources" excludes="**/thumbs.db" />
</copy>
<!-- Build jar -->
<delete file="${project.jar}" />
<jar index="true" jarfile="${project.jar}">
<fileset dir="${project.build.dir}">
<include name="**/*" />
</fileset>
<manifest>
<attribute name="Main-Class" value="${project.mainclass}" />
</manifest>
<indexjars>
<fileset dir="${basedir}/lib" />
</indexjars>
</jar>
<!-- Delete the deploy folder -->
<delete dir="${basedir}/deploy" />
<!-- Create deployment folder structure -->
<mkdir dir="${basedir}/deploy" />
<copy todir="${basedir}/deploy" file="${project.jar}" />
<copy todir="${basedir}/deploy/lib">
<fileset dir="${basedir}/lib">
<include name="**/*.jar" />
</fileset>
</copy>
<copy todir="${basedir}/deploy">
<fileset dir="${basedir}/service">
<include name="**/*" />
</fileset>
<fileset dir="${basedir}">
<include name="*.cmd" />
<include name="*.properties" />
</fileset>
</copy>
<!-- Create Zip deployment -->
<zip destfile="${distribution.zipfile}">
<fileset dir="${basedir}/deploy">
<include name="**/*" />
</fileset>
</zip>
<!-- Delete the deploy folder -->
<delete dir="${basedir}/deploy" />
<!-- Cleanup builds -->
<delete>
<fileset dir="${basedir}">
<include name="${project.jar}" />
</fileset>
</delete>
</target>
</project>

+ 1
- 0
gitblit.cmd View File

@@ -0,0 +1 @@
@java -jar gitblit.jar

+ 96
- 0
gitblit.properties View File

@@ -0,0 +1,96 @@
#
# GIT Servlet Settings
#
# Base folder for repositories
# Use forward slashes on Windows!!
repositoriesFolder = c:/projects/git
# Export all repositories
# if false, each exported repository must have a .git/git-daemon-export-ok file
exportAll = true
# Search repositories folder for nested repositories
nestedRepositories = true
# The root clone url
cloneUrl = https://localhost/git/
#
# Authentication Settings
#
# Require authentication for http push/pull of git repositories
authenticateAccess = true
# Simple user realm file to authenticate users for push/pull
realmFile = users.properties
# User roles for push/pull git repository access
# (* is the wildcard for any role)
gitRoles = *
# User roles for administrative features such
# as create repository, edit repository description,
# and set repository owner.
# (* is the wildcard for any role)
adminRoles = *
#
# Server Settings
#
debug = true
tempFolder = temp
log4jPattern = %-5p %d{MM-dd HH:mm:ss.SSS} %-20.20c{1} %m%n
# Aggressive garbage collection will run the collector on every generated page
# this slows down page generation but improves heap consumption
aggressiveGC = true
#
# Git:Blit UI Settings
#
siteName = Git:Blit
allowAdministration = true
indexMessage = Welcome to Git:Blit!<br>A quick and easy way to host your own GIT repositories.<br>Built with <a href="http://eclipse.org/jgit">JGit</a>, <a href="http://wicket.apache.org">Wicket</a>, <a href="http://code.google.com/p/google-code-prettify/">google-code-prettify</a>, <a href="http://eclipse.org/jetty">Jetty</a>, <a href="http://www.slf4j.org">SLF4J</a>, <a href="http://logging.apache.org/log4j">Log4j</a>, and <a href="http://jcommander.org">JCommander</a>.
timestampFormat = h:mm a
datestampShortFormat = yyyy-MM-dd
datestampLongFormat = EEEE, MMMM d, yyyy
datetimestampShortFormat = yyyy-MM-dd h:mm a
datetimestampLongFormat = EEEE, MMMM d, yyyy h:mm a
# Registered extensions for google-code-prettify
prettyPrintExtensions = c cpp cs css htm html java js php pl prefs properties py rb sh sql xml vb
# Image extensions
imageExtensions = bmp jpg gif png
# Registered extensions for binary blobs
binaryExtensions = jar pdf tar.gz zip
# Example global regex substitutions
regex.global.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://somehost/bug/$3">Bug-Id: $3</a>
regex.global.changeid = \\b(Change-Id:\\s*)([A-Za-z0-9]*)\\b!!!<a href="http://somehost/changeid/$2">Change-Id: $2</a>
# Example per-repository regex substitutions overrides global
regex.myrepository.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://elsewhere/bug/$3">Bug-Id: $3</a>
#
# Jetty Settings
#
# use NIO connectors. If false, socket connectors will be used.
useNio = true
# Standard http port to serve. <= 0 disables this connector.
httpPort = 0
# Secure/SSL https port to serve. <= 0 disables this connector.
httpsPort = 443
# Password for SSL keystore (keystore password and certificate password must match)
storePassword = dosomegit
# Port for shutdown monitor to listen on.
shutdownPort = 8081

+ 2
- 0
makekeystore.cmd View File

@@ -0,0 +1,2 @@
@del keystore
@keytool -keystore keystore -alias localhost -genkey -keyalg RSA -dname "CN=localhost, OU=Git:Blit, O=Git:Blit, L=Some Town, ST=Some State, C=US"

+ 12
- 0
makepassword.cmd View File

@@ -0,0 +1,12 @@
@if [%1]==[] goto missingparameters
@if [%2]==[] goto missingparameters
@java -cp "%CD%\ext\*" org.eclipse.jetty.http.security.Password %1 %2
@goto end
:missingparameters
@echo Usage:
@echo makepassword username password
@echo.
:end

+ 11
- 0
makerepository.cmd View File

@@ -0,0 +1,11 @@
@if [%1]==[] goto missingparameters
@java -cp gitblit.jar;"%CD%\lib\*" com.gitblit.MakeRepository --create %1
@goto end
:missingparameters
@echo Usage:
@echo makerepository path_to_repository
@echo.
:end

BIN
resources/arrow_down.png View File


BIN
resources/arrow_off.png View File


BIN
resources/arrow_up.png View File


BIN
resources/git-favicon.png View File


+ 56
- 0
resources/gitblit.css View File

@@ -0,0 +1,56 @@
/*
JGitWeb css.
*/
body, table, tr, th, td { font-size: 13px; }
table.object_header td, div.page_body, table.diff_tree td {
font-size: 12px;
}
table.diff_tree td div.link {
padding: 2px 5px;
font-family: sans-serif;
font-size: 9px;
}
div.link {
padding: 2px 5px;
font-family: sans-serif;
font-size: 9px;
}
pre.prettyprint, pre.plainprint {
font-size:12px;
border:0px;
}
div.page_nav2 {
padding: 0px 8px 8px 8px;
}
table.project_list tr th a { padding-right: 15px; background-position: right; background-repeat:no-repeat; }
table.project_list tr th.wicket_orderDown a {font-weight: bold; background-image: url(arrow_down.png); }
table.project_list tr th.wicket_orderUp a { font-weight: bold; background-image: url(arrow_up.png); }
table.project_list tr th.wicket_orderNone a { font-weight: normal; background-image: url(arrow_off.png); }
/* age0: age < 60*60*2 */
table.project_list .age0 {
color: #009900;
font-style: italic;
font-weight: bold;
}
/* age1: 60*60*2 <= age < 60*60*24*2 */
table.project_list .age1 {
color: #009900;
font-style: italic;
}
/* age2: 60*60*24*2 <= age */
table.project_list .age2 {
font-style: italic;
}
table.diff_tree td.size {
width:80px;
}

BIN
resources/gitblt-logo.png View File


BIN
resources/gitblt.png View File


BIN
resources/gitblt2.png View File


BIN
resources/gitblt3.png View File


BIN
resources/gitblt_25.png View File


+ 604
- 0
resources/gitweb.css View File

@@ -0,0 +1,604 @@
body {
font-family: sans-serif;
font-size: small;
border: solid #d9d8d1;
border-width: 1px;
margin: 10px;
background-color: #ffffff;
color: #000000;
}
a {
color: #0000cc;
}
a:hover, a:visited, a:active {
color: #880000;
}
span.cntrl {
border: dashed #aaaaaa;
border-width: 1px;
padding: 0px 2px 0px 2px;
margin: 0px 2px 0px 2px;
}
img.logo {
float: right;
border-width: 0px;
}
img.avatar {
vertical-align: middle;
}
a.list img.avatar {
border-style: none;
}
div.page_header {
height: 25px;
padding: 8px;
font-size: 150%;
font-weight: bold;
background-color: #d9d8d1;
}
div.page_header a:visited, a.header {
color: #0000cc;
}
div.page_header a:hover {
color: #880000;
}
div.page_nav {
padding: 8px;
}
div.page_nav a:visited {
color: #0000cc;
}
div.page_path {
padding: 8px;
font-weight: bold;
border: solid #d9d8d1;
border-width: 0px 0px 1px;
}
div.cachetime {
float: left;
margin-right: 10px;
color: #555555;
}
div.page_footer {
height: 17px;
padding: 4px 8px;
background-color: #d9d8d1;
}
div.page_footer_text {
float: left;
color: #555555;
font-style: italic;
}
div#generating_info {
margin: 4px;
font-size: smaller;
text-align: center;
color: #505050;
}
div.page_body {
padding: 8px;
font-family: monospace;
}
div.title, a.title {
display: block;
padding: 6px 8px;
font-weight: bold;
background-color: #edece6;
text-decoration: none;
color: #000000;
}
div.readme {
padding: 8px;
}
a.title:hover {
background-color: #d9d8d1;
}
div.title_text {
padding: 6px 0px;
border: solid #d9d8d1;
border-width: 0px 0px 1px;
font-family: monospace;
}
div.log_body {
padding: 8px 8px 8px 150px;
}
span.age {
position: relative;
float: left;
width: 142px;
font-style: italic;
}
span.signoff {
color: #888888;
}
div.log_link {
padding: 0px 8px;
font-size: 70%;
font-family: sans-serif;
font-style: normal;
position: relative;
float: left;
width: 136px;
}
div.list_head {
padding: 6px 8px 4px;
border: solid #d9d8d1;
border-width: 1px 0px 0px;
font-style: italic;
}
.author_date, .author {
font-style: italic;
}
div.author_date {
padding: 8px;
border: solid #d9d8d1;
border-width: 0px 0px 1px 0px;
}
a.list {
text-decoration: none;
color: #000000;
}
a.subject, a.name {
font-weight: bold;
}
table.tags a.subject {
font-weight: normal;
}
a.list:hover {
text-decoration: underline;
color: #880000;
}
a.text {
text-decoration: none;
color: #0000cc;
}
a.text:visited {
text-decoration: none;
color: #880000;
}
a.text:hover {
text-decoration: underline;
color: #880000;
}
table {
padding: 8px 4px;
border-spacing: 0;
}
table.diff_tree {
font-family: monospace;
}
table.combined.diff_tree th {
text-align: center;
}
table.combined.diff_tree td {
padding-right: 24px;
}
table.combined.diff_tree th.link,
table.combined.diff_tree td.link {
padding: 0px 2px;
}
table.combined.diff_tree td.nochange a {
color: #6666ff;
}
table.combined.diff_tree td.nochange a:hover,
table.combined.diff_tree td.nochange a:visited {
color: #d06666;
}
table.blame {
border-collapse: collapse;
}
table.blame td {
padding: 0px 5px;
font-size: 100%;
vertical-align: top;
}
th {
padding: 2px 5px;
font-size: 100%;
text-align: left;
}
/* do not change row style on hover for 'blame' view */
tr.light,
table.blame .light:hover {
background-color: #ffffff;
}
tr.dark,
table.blame .dark:hover {
background-color: #f6f6f0;
}
/* currently both use the same, but it can change */
tr.light:hover,
tr.dark:hover {
background-color: #edece6;
}
/* boundary commits in 'blame' view */
/* and commits without "previous" */
tr.boundary td.sha1,
tr.no-previous td.linenr {
font-weight: bold;
}
/* for 'blame_incremental', during processing */
tr.color1 { background-color: #f6fff6; }
tr.color2 { background-color: #f6f6ff; }
tr.color3 { background-color: #fff6f6; }
td {
padding: 2px 5px;
font-size: 100%;
vertical-align: top;
}
td.link, td.selflink {
padding: 2px 5px;
font-family: sans-serif;
font-size: 70%;
}
td.selflink {
padding-right: 0px;
}
td.sha1 {
font-family: monospace;
}
.error {
color: red;
background-color: yellow;
}
td.current_head {
text-decoration: underline;
}
table.diff_tree span.file_status.new {
color: #008000;
}
table.diff_tree span.file_status.deleted {
color: #c00000;
}
table.diff_tree span.file_status.moved,
table.diff_tree span.file_status.mode_chnge {
color: #777777;
}
table.diff_tree span.file_status.copied {
color: #70a070;
}
/* noage: "No commits" */
table.project_list td.noage {
color: #808080;
font-style: italic;
}
/* age2: 60*60*24*2 <= age */
table.project_list td.age2, table.blame td.age2 {
font-style: italic;
}
/* age1: 60*60*2 <= age < 60*60*24*2 */
table.project_list td.age1 {
color: #009900;
font-style: italic;
}
table.blame td.age1 {
color: #009900;
background: transparent;
}
/* age0: age < 60*60*2 */
table.project_list td.age0 {
color: #009900;
font-style: italic;
font-weight: bold;
}
table.blame td.age0 {
color: #009900;
background: transparent;
font-weight: bold;
}
td.pre, div.pre, div.diff {
font-family: monospace;
font-size: 12px;
white-space: pre;
}
td.mode {
font-family: monospace;
}
/* progress of blame_interactive */
div#progress_bar {
height: 2px;
margin-bottom: -2px;
background-color: #d8d9d0;
}
div#progress_info {
float: right;
text-align: right;
}
/* format of (optional) objects size in 'tree' view */
td.size {
font-family: monospace;
text-align: right;
}
/* styling of diffs (patchsets): commitdiff and blobdiff views */
div.diff.header,
div.diff.extended_header {
white-space: normal;
}
div.diff.header {
font-weight: bold;
background-color: #edece6;
margin-top: 4px;
padding: 4px 0px 2px 0px;
border: solid #d9d8d1;
border-width: 1px 0px 1px 0px;
}
div.diff.header a.path {
text-decoration: underline;
}
div.diff.extended_header,
div.diff.extended_header a.path,
div.diff.extended_header a.hash {
color: #777777;
}
div.diff.extended_header .info {
color: #b0b0b0;
}
div.diff.extended_header {
background-color: #f6f5ee;
padding: 2px 0px 2px 0px;
}
div.diff a.list,
div.diff a.path,
div.diff a.hash {
text-decoration: none;
}
div.diff a.list:hover,
div.diff a.path:hover,
div.diff a.hash:hover {
text-decoration: underline;
}
div.diff.to_file a.path,
div.diff.to_file {
color: #007000;
}
div.diff.add {
color: #008800;
}
div.diff.from_file a.path,
div.diff.from_file {
color: #aa0000;
}
div.diff.rem {
color: #cc0000;
}
div.diff.chunk_header a,
div.diff.chunk_header {
color: #990099;
}
div.diff.chunk_header {
border: dotted #ffe0ff;
border-width: 1px 0px 0px 0px;
margin-top: 2px;
}
div.diff.chunk_header span.chunk_info {
background-color: #ffeeff;
}
div.diff.chunk_header span.section {
color: #aa22aa;
}
div.diff.incomplete {
color: #cccccc;
}
div.diff.nodifferences {
font-weight: bold;
color: #600000;
}
div.index_include {
border: solid #d9d8d1;
border-width: 0px 0px 1px;
padding: 12px 8px;
}
div.search {
font-size: 100%;
font-weight: normal;
margin: 4px 8px;
float: right;
top: 56px;
right: 12px
}
p.projsearch {
text-align: center;
}
td.linenr {
text-align: right;
}
a.linenr {
color: #999999;
text-decoration: none
}
a.rss_logo {
float: right;
padding: 3px 0px;
width: 35px;
line-height: 10px;
border: 1px solid;
border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
color: #ffffff;
background-color: #ff6600;
font-weight: bold;
font-family: sans-serif;
font-size: 70%;
text-align: center;
text-decoration: none;
}
a.rss_logo:hover {
background-color: #ee5500;
}
a.rss_logo.generic {
background-color: #ff8800;
}
a.rss_logo.generic:hover {
background-color: #ee7700;
}
span.refs span {
padding: 0px 4px;
font-size: 70%;
font-weight: normal;
border: 1px solid;
background-color: #ffaaff;
border-color: #ffccff #ff00ee #ff00ee #ffccff;
}
span.refs span a {
text-decoration: none;
color: inherit;
}
span.refs span a:hover {
text-decoration: underline;
}
span.refs span.indirect {
font-style: italic;
}
span.refs span.ref {
background-color: #aaaaff;
border-color: #ccccff #0033cc #0033cc #ccccff;
}
span.refs span.tag {
background-color: #ffffaa;
border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
}
span.refs span.head {
background-color: #aaffaa;
border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
}
span.atnight {
color: #cc0000;
}
span.match {
color: #e00000;
}
div.binary {
font-style: italic;
}
div.remote {
margin: .5em;
border: 1px solid #d9d8d1;
display: inline-block;
}
/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */
/* Highlighting theme definition: */
.num { color:#2928ff; }
.esc { color:#ff00ff; }
.str { color:#ff0000; }
.dstr { color:#818100; }
.slc { color:#838183; font-style:italic; }
.com { color:#838183; font-style:italic; }
.dir { color:#008200; }
.sym { color:#000000; }
.line { color:#555555; }
.kwa { color:#000000; font-weight:bold; }
.kwb { color:#830000; }
.kwc { color:#000000; font-weight:bold; }
.kwd { color:#010181; }

+ 2
- 0
resources/prettify/lang-apollo.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,
null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["apollo","agc","aea"])

+ 2
- 0
resources/prettify/lang-css.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[ \t\r\n\f]+/,null," \t\r\n\u000c"]],[["str",/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],["str",/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],["kwd",/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],
["com",/^(?:<!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#(?:[0-9a-f]{3}){1,2}/i],["pln",/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],["pun",/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^\)\"\']+/]]),["css-str"])

+ 2
- 0
resources/prettify/lang-hs.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\x0B\x0C\r ]+/,null,"\t\n\u000b\u000c\r "],["str",/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/,
null],["pln",/^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],["pun",/^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]]),["hs"])

+ 2
- 0
resources/prettify/lang-lisp.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(/,null,"("],["clo",/^\)/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
null],["lit",/^[+\-]?(?:0x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["cl","el","lisp","scm"])

+ 2
- 0
resources/prettify/lang-lua.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,"\"'"]],[["com",/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],["str",/^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],["kwd",/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],["lit",/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],
["pln",/^[a-z_]\w*/i],["pun",/^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]]),["lua"])

+ 2
- 0
resources/prettify/lang-ml.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["com",/^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],
["lit",/^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^(?:[a-z_]\w*[!?#]?|``[^\r\n\t`]*(?:``|$))/i],["pun",/^[^\t\n\r \xA0\"\'\w]+/]]),["fs","ml"])

+ 1
- 0
resources/prettify/lang-proto.js View File

@@ -0,0 +1 @@
PR.registerLangHandler(PR.sourceDecorator({keywords:"bool bytes default double enum extend extensions false fixed32 fixed64 float group import int32 int64 max message option optional package repeated required returns rpc service sfixed32 sfixed64 sint32 sint64 string syntax to true uint32 uint64",cStyleComments:true}),["proto"])

+ 2
- 0
resources/prettify/lang-scala.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:(?:""(?:""?(?!")|[^\\"]|\\.)*"{0,3})|(?:[^"\r\n\\]|\\.)*"?))/,null,'"'],["lit",/^`(?:[^\r\n\\`]|\\.)*`?/,null,"`"],["pun",/^[!#%&()*+,\-:;<=>?@\[\\\]^{|}~]+/,null,"!#%&()*+,-:;<=>?@[\\]^{|}~"]],[["str",/^'(?:[^\r\n\\']|\\(?:'|[^\r\n']+))'/],["lit",/^'[a-zA-Z_$][\w$]*(?!['$\w])/],["kwd",/^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/],
["lit",/^(?:true|false|null|this)\b/],["lit",/^(?:(?:0(?:[0-7]+|X[0-9A-F]+))L?|(?:(?:0|[1-9][0-9]*)(?:(?:\.[0-9]+)?(?:E[+\-]?[0-9]+)?F?|L?))|\\.[0-9]+(?:E[+\-]?[0-9]+)?F?)/i],["typ",/^[$_]*[A-Z][_$A-Z0-9]*[a-z][\w$]*/],["pln",/^[$a-zA-Z_][\w$]*/],["com",/^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/],["pun",/^(?:\.+|\/)/]]),["scala"])

+ 2
- 0
resources/prettify/lang-sql.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],["kwd",/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,
null],["lit",/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^[a-z_][\w-]*/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),["sql"])

+ 2
- 0
resources/prettify/lang-vb.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0\u2028\u2029]+/,null,"\t\n\r \u00a0\u2028\u2029"],["str",/^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i,null,'"\u201c\u201d'],["com",/^[\'\u2018\u2019][^\r\n\u2028\u2029]*/,null,"'\u2018\u2019"]],[["kwd",/^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i,
null],["com",/^REM[^\r\n\u2028\u2029]*/i],["lit",/^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i],["pln",/^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*\])/i],["pun",/^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/],["pun",/^(?:\[|\])/]]),["vb","vbs"])

+ 3
- 0
resources/prettify/lang-vhdl.js View File

@@ -0,0 +1,3 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"]],[["str",/^(?:[BOX]?"(?:[^\"]|"")*"|'.')/i],["com",/^--[^\r\n]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i,
null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^\'(?:ACTIVE|ASCENDING|BASE|DELAYED|DRIVING|DRIVING_VALUE|EVENT|HIGH|IMAGE|INSTANCE_NAME|LAST_ACTIVE|LAST_EVENT|LAST_VALUE|LEFT|LEFTOF|LENGTH|LOW|PATH_NAME|POS|PRED|QUIET|RANGE|REVERSE_RANGE|RIGHT|RIGHTOF|SIMPLE_NAME|STABLE|SUCC|TRANSACTION|VAL|VALUE)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w\\.]+#(?:[+\-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:E[+\-]?\d+(?:_\d+)*)?)/i],
["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0\-\"\']*/]]),["vhdl","vhd"])

+ 2
- 0
resources/prettify/lang-wiki.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t \xA0a-gi-z0-9]+/,null,"\t \u00a0abcdefgijklmnopqrstuvwxyz0123456789"],["pun",/^[=*~\^\[\]]+/,null,"=*~^[]"]],[["lang-wiki.meta",/(?:^^|\r\n?|\n)(#[a-z]+)\b/],["lit",/^(?:[A-Z][a-z][a-z0-9]+[A-Z][a-z][a-zA-Z0-9]+)\b/],["lang-",/^\{\{\{([\s\S]+?)\}\}\}/],["lang-",/^`([^\r\n`]+)`/],["str",/^https?:\/\/[^\/?#\s]*(?:\/[^?#\s]*)?(?:\?[^#\s]*)?(?:#\S*)?/i],["pln",/^(?:\r\n|[\s\S])[^#=*~^A-Zh\{`\[\r\n]*/]]),["wiki"]);
PR.registerLangHandler(PR.createSimpleLexer([["kwd",/^#[a-z]+/i,null,"#"]],[]),["wiki.meta"])

+ 2
- 0
resources/prettify/lang-yaml.js View File

@@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:|>?]+/,null,":|>?"],["dec",/^%(?:YAML|TAG)[^#\r\n]+/,null,"%"],["typ",/^[&]\S+/,null,"&"],["typ",/^!\S*/,null,"!"],["str",/^"(?:[^\\"]|\\.)*(?:"|$)/,null,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,null,"'"],["com",/^#[^\r\n]*/,null,"#"],["pln",/^\s+/,null," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\r\n]|$)/],["pun",/^-/],["kwd",/^\w+:[ \r\n]/],["pln",/^\w+/]]),
["yaml","yml"])

+ 1
- 0
resources/prettify/prettify.css View File

@@ -0,0 +1 @@
.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun{color:#660}.pln{color:#000}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec{color:#606}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}@media print{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun{color:#440}.pln{color:#000}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}

+ 33
- 0
resources/prettify/prettify.js View File

@@ -0,0 +1,33 @@
window.PR_SHOULD_USE_CONTINUATION=true;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var y=navigator&&navigator.userAgent&&navigator.userAgent.match(/\bMSIE ([678])\./);y=y?+y[1]:false;window._pr_isIE6=function(){return y};return y};
(function(){function y(b){return b.replace(L,"&amp;").replace(M,"&lt;").replace(N,"&gt;")}function H(b,f,i){switch(b.nodeType){case 1:var o=b.tagName.toLowerCase();f.push("<",o);var l=b.attributes,n=l.length;if(n){if(i){for(var r=[],j=n;--j>=0;)r[j]=l[j];r.sort(function(q,m){return q.name<m.name?-1:q.name===m.name?0:1});l=r}for(j=0;j<n;++j){r=l[j];r.specified&&f.push(" ",r.name.toLowerCase(),'="',r.value.replace(L,"&amp;").replace(M,"&lt;").replace(N,"&gt;").replace(X,"&quot;"),'"')}}f.push(">");
for(l=b.firstChild;l;l=l.nextSibling)H(l,f,i);if(b.firstChild||!/^(?:br|link|img)$/.test(o))f.push("</",o,">");break;case 3:case 4:f.push(y(b.nodeValue));break}}function O(b){function f(c){if(c.charAt(0)!=="\\")return c.charCodeAt(0);switch(c.charAt(1)){case "b":return 8;case "t":return 9;case "n":return 10;case "v":return 11;case "f":return 12;case "r":return 13;case "u":case "x":return parseInt(c.substring(2),16)||c.charCodeAt(1);case "0":case "1":case "2":case "3":case "4":case "5":case "6":case "7":return parseInt(c.substring(1),
8);default:return c.charCodeAt(1)}}function i(c){if(c<32)return(c<16?"\\x0":"\\x")+c.toString(16);c=String.fromCharCode(c);if(c==="\\"||c==="-"||c==="["||c==="]")c="\\"+c;return c}function o(c){var d=c.substring(1,c.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));c=[];for(var a=[],k=d[0]==="^",e=k?1:0,h=d.length;e<h;++e){var g=d[e];switch(g){case "\\B":case "\\b":case "\\D":case "\\d":case "\\S":case "\\s":case "\\W":case "\\w":c.push(g);
continue}g=f(g);var s;if(e+2<h&&"-"===d[e+1]){s=f(d[e+2]);e+=2}else s=g;a.push([g,s]);if(!(s<65||g>122)){s<65||g>90||a.push([Math.max(65,g)|32,Math.min(s,90)|32]);s<97||g>122||a.push([Math.max(97,g)&-33,Math.min(s,122)&-33])}}a.sort(function(v,w){return v[0]-w[0]||w[1]-v[1]});d=[];g=[NaN,NaN];for(e=0;e<a.length;++e){h=a[e];if(h[0]<=g[1]+1)g[1]=Math.max(g[1],h[1]);else d.push(g=h)}a=["["];k&&a.push("^");a.push.apply(a,c);for(e=0;e<d.length;++e){h=d[e];a.push(i(h[0]));if(h[1]>h[0]){h[1]+1>h[0]&&a.push("-");
a.push(i(h[1]))}}a.push("]");return a.join("")}function l(c){for(var d=c.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),a=d.length,k=[],e=0,h=0;e<a;++e){var g=d[e];if(g==="(")++h;else if("\\"===g.charAt(0))if((g=+g.substring(1))&&g<=h)k[g]=-1}for(e=1;e<k.length;++e)if(-1===k[e])k[e]=++n;for(h=e=0;e<a;++e){g=d[e];if(g==="("){++h;if(k[h]===undefined)d[e]="(?:"}else if("\\"===
g.charAt(0))if((g=+g.substring(1))&&g<=h)d[e]="\\"+k[h]}for(h=e=0;e<a;++e)if("^"===d[e]&&"^"!==d[e+1])d[e]="";if(c.ignoreCase&&r)for(e=0;e<a;++e){g=d[e];c=g.charAt(0);if(g.length>=2&&c==="[")d[e]=o(g);else if(c!=="\\")d[e]=g.replace(/[a-zA-Z]/g,function(s){s=s.charCodeAt(0);return"["+String.fromCharCode(s&-33,s|32)+"]"})}return d.join("")}for(var n=0,r=false,j=false,q=0,m=b.length;q<m;++q){var t=b[q];if(t.ignoreCase)j=true;else if(/[a-z]/i.test(t.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,
""))){r=true;j=false;break}}var p=[];q=0;for(m=b.length;q<m;++q){t=b[q];if(t.global||t.multiline)throw Error(""+t);p.push("(?:"+l(t)+")")}return RegExp(p.join("|"),j?"gi":"g")}function Y(b){var f=0;return function(i){for(var o=null,l=0,n=0,r=i.length;n<r;++n)switch(i.charAt(n)){case "\t":o||(o=[]);o.push(i.substring(l,n));l=b-f%b;for(f+=l;l>=0;l-=16)o.push(" ".substring(0,l));l=n+1;break;case "\n":f=0;break;default:++f}if(!o)return i;o.push(i.substring(l));return o.join("")}}function I(b,
f,i,o){if(f){b={source:f,c:b};i(b);o.push.apply(o,b.d)}}function B(b,f){var i={},o;(function(){for(var r=b.concat(f),j=[],q={},m=0,t=r.length;m<t;++m){var p=r[m],c=p[3];if(c)for(var d=c.length;--d>=0;)i[c.charAt(d)]=p;p=p[1];c=""+p;if(!q.hasOwnProperty(c)){j.push(p);q[c]=null}}j.push(/[\0-\uffff]/);o=O(j)})();var l=f.length;function n(r){for(var j=r.c,q=[j,z],m=0,t=r.source.match(o)||[],p={},c=0,d=t.length;c<d;++c){var a=t[c],k=p[a],e=void 0,h;if(typeof k==="string")h=false;else{var g=i[a.charAt(0)];
if(g){e=a.match(g[1]);k=g[0]}else{for(h=0;h<l;++h){g=f[h];if(e=a.match(g[1])){k=g[0];break}}e||(k=z)}if((h=k.length>=5&&"lang-"===k.substring(0,5))&&!(e&&typeof e[1]==="string")){h=false;k=P}h||(p[a]=k)}g=m;m+=a.length;if(h){h=e[1];var s=a.indexOf(h),v=s+h.length;if(e[2]){v=a.length-e[2].length;s=v-h.length}k=k.substring(5);I(j+g,a.substring(0,s),n,q);I(j+g+s,h,Q(k,h),q);I(j+g+v,a.substring(v),n,q)}else q.push(j+g,k)}r.d=q}return n}function x(b){var f=[],i=[];if(b.tripleQuotedStrings)f.push([A,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
null,"'\""]);else b.multiLineStrings?f.push([A,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):f.push([A,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);b.verbatimStrings&&i.push([A,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);if(b.hashComments)if(b.cStyleComments){f.push([C,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]);i.push([A,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
null])}else f.push([C,/^#[^\r\n]*/,null,"#"]);if(b.cStyleComments){i.push([C,/^\/\/[^\r\n]*/,null]);i.push([C,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}b.regexLiterals&&i.push(["lang-regex",RegExp("^"+Z+"(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)")]);b=b.keywords.replace(/^\s+|\s+$/g,"");b.length&&i.push([R,RegExp("^(?:"+b.replace(/\s+/g,"|")+")\\b"),null]);f.push([z,/^\s+/,null," \r\n\t\u00a0"]);i.push([J,/^@[a-z_$][a-z_$@0-9]*/i,null],[S,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/,
null],[z,/^[a-z_$][a-z_$@0-9]*/i,null],[J,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],[E,/^.[^\s\w\.$@\'\"\`\/\#]*/,null]);return B(f,i)}function $(b){function f(D){if(D>r){if(j&&j!==q){n.push("</span>");j=null}if(!j&&q){j=q;n.push('<span class="',j,'">')}var T=y(p(i.substring(r,D))).replace(e?d:c,"$1&#160;");e=k.test(T);n.push(T.replace(a,s));r=D}}var i=b.source,o=b.g,l=b.d,n=[],r=0,j=null,q=null,m=0,t=0,p=Y(window.PR_TAB_WIDTH),c=/([\r\n ]) /g,
d=/(^| ) /gm,a=/\r\n?|\n/g,k=/[ \r\n]$/,e=true,h=window._pr_isIE6();h=h?b.b.tagName==="PRE"?h===6?"&#160;\r\n":h===7?"&#160;<br>\r":"&#160;\r":"&#160;<br />":"<br />";var g=b.b.className.match(/\blinenums\b(?::(\d+))?/),s;if(g){for(var v=[],w=0;w<10;++w)v[w]=h+'</li><li class="L'+w+'">';var F=g[1]&&g[1].length?g[1]-1:0;n.push('<ol class="linenums"><li class="L',F%10,'"');F&&n.push(' value="',F+1,'"');n.push(">");s=function(){var D=v[++F%10];return j?"</span>"+D+'<span class="'+j+'">':D}}else s=h;
for(;;)if(m<o.length?t<l.length?o[m]<=l[t]:true:false){f(o[m]);if(j){n.push("</span>");j=null}n.push(o[m+1]);m+=2}else if(t<l.length){f(l[t]);q=l[t+1];t+=2}else break;f(i.length);j&&n.push("</span>");g&&n.push("</li></ol>");b.a=n.join("")}function u(b,f){for(var i=f.length;--i>=0;){var o=f[i];if(G.hasOwnProperty(o))"console"in window&&console.warn("cannot override language handler %s",o);else G[o]=b}}function Q(b,f){b&&G.hasOwnProperty(b)||(b=/^\s*</.test(f)?"default-markup":"default-code");return G[b]}
function U(b){var f=b.f,i=b.e;b.a=f;try{var o,l=f.match(aa);f=[];var n=0,r=[];if(l)for(var j=0,q=l.length;j<q;++j){var m=l[j];if(m.length>1&&m.charAt(0)==="<"){if(!ba.test(m))if(ca.test(m)){f.push(m.substring(9,m.length-3));n+=m.length-12}else if(da.test(m)){f.push("\n");++n}else if(m.indexOf(V)>=0&&m.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)){var t=m.match(W)[2],p=1,c;c=j+1;a:for(;c<q;++c){var d=l[c].match(W);if(d&&
d[2]===t)if(d[1]==="/"){if(--p===0)break a}else++p}if(c<q){r.push(n,l.slice(j,c+1).join(""));j=c}else r.push(n,m)}else r.push(n,m)}else{var a;p=m;var k=p.indexOf("&");if(k<0)a=p;else{for(--k;(k=p.indexOf("&#",k+1))>=0;){var e=p.indexOf(";",k);if(e>=0){var h=p.substring(k+3,e),g=10;if(h&&h.charAt(0)==="x"){h=h.substring(1);g=16}var s=parseInt(h,g);isNaN(s)||(p=p.substring(0,k)+String.fromCharCode(s)+p.substring(e+1))}}a=p.replace(ea,"<").replace(fa,">").replace(ga,"'").replace(ha,'"').replace(ia," ").replace(ja,
"&")}f.push(a);n+=a.length}}o={source:f.join(""),h:r};var v=o.source;b.source=v;b.c=0;b.g=o.h;Q(i,v)(b);$(b)}catch(w){if("console"in window)console.log(w&&w.stack?w.stack:w)}}var A="str",R="kwd",C="com",S="typ",J="lit",E="pun",z="pln",P="src",V="nocode",Z=function(){for(var b=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=",
"~","break","case","continue","delete","do","else","finally","instanceof","return","throw","try","typeof"],f="(?:^^|[+-]",i=0;i<b.length;++i)f+="|"+b[i].replace(/([^=<>:&a-z])/g,"\\$1");f+=")\\s*";return f}(),L=/&/g,M=/</g,N=/>/g,X=/\"/g,ea=/&lt;/g,fa=/&gt;/g,ga=/&apos;/g,ha=/&quot;/g,ja=/&amp;/g,ia=/&nbsp;/g,ka=/[\r\n]/g,K=null,aa=RegExp("[^<]+|<!--[\\s\\S]*?--\>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z](?:[^>\"']|'[^']*'|\"[^\"]*\")*>|<","g"),ba=/^<\!--/,ca=/^<!\[CDATA\[/,da=/^<br\b/i,W=/^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/,
la=x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename using virtual wchar_t where break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof debugger eval export function get null set undefined var with Infinity NaN caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END break continue do else for if return while case done elif esac eval fi function in local set then until ",
hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true}),G={};u(la,["default-code"]);u(B([],[[z,/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],[C,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[E,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup",
"htm","html","mxml","xhtml","xml","xsl"]);u(B([[z,/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[E,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],
["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);u(B([],[["atv",/^[\s\S]+/]]),["uq.val"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename using virtual wchar_t where ",
hashComments:true,cStyleComments:true}),["c","cc","cpp","cxx","cyc","m"]);u(x({keywords:"null true false"}),["json"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ",
hashComments:true,cStyleComments:true,verbatimStrings:true}),["cs"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",
cStyleComments:true}),["java"]);u(x({keywords:"break continue do else for if return while case done elif esac eval fi function in local set then until ",hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);u(x({keywords:"break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);
u(x({keywords:"caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);u(x({keywords:"break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",hashComments:true,
multiLineStrings:true,regexLiterals:true}),["rb"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof debugger eval export function get null set undefined var with Infinity NaN ",cStyleComments:true,regexLiterals:true}),["js"]);u(B([],[[A,/^[\s\S]+/]]),
["regex"]);window.PR_normalizedHtml=H;window.prettyPrintOne=function(b,f){var i={f:b,e:f};U(i);return i.a};window.prettyPrint=function(b){function f(){for(var t=window.PR_SHOULD_USE_CONTINUATION?j.now()+250:Infinity;q<o.length&&j.now()<t;q++){var p=o[q];if(p.className&&p.className.indexOf("prettyprint")>=0){var c=p.className.match(/\blang-(\w+)\b/);if(c)c=c[1];for(var d=false,a=p.parentNode;a;a=a.parentNode)if((a.tagName==="pre"||a.tagName==="code"||a.tagName==="xmp")&&a.className&&a.className.indexOf("prettyprint")>=
0){d=true;break}if(!d){a=p;if(null===K){d=document.createElement("PRE");d.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));K=!/</.test(d.innerHTML)}if(K){d=a.innerHTML;if("XMP"===a.tagName)d=y(d);else{a=a;if("PRE"===a.tagName)a=true;else if(ka.test(d)){var k="";if(a.currentStyle)k=a.currentStyle.whiteSpace;else if(window.getComputedStyle)k=window.getComputedStyle(a,null).whiteSpace;a=!k||k==="pre"}else a=true;a||(d=d.replace(/(<br\s*\/?>)[\r\n]+/g,"$1").replace(/(?:[\r\n]+[ \t]*)+/g,
" "))}d=d}else{d=[];for(a=a.firstChild;a;a=a.nextSibling)H(a,d);d=d.join("")}d=d.replace(/(?:\r\n?|\n)$/,"");m={f:d,e:c,b:p};U(m);if(p=m.a){c=m.b;if("XMP"===c.tagName){d=document.createElement("PRE");for(a=0;a<c.attributes.length;++a){k=c.attributes[a];if(k.specified)if(k.name.toLowerCase()==="class")d.className=k.value;else d.setAttribute(k.name,k.value)}d.innerHTML=p;c.parentNode.replaceChild(d,c)}else c.innerHTML=p}}}}if(q<o.length)setTimeout(f,250);else b&&b()}for(var i=[document.getElementsByTagName("pre"),
document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],o=[],l=0;l<i.length;++l)for(var n=0,r=i[l].length;n<r;++n)o.push(i[l][n]);i=null;var j=Date;j.now||(j={now:function(){return(new Date).getTime()}});var q=0,m;f()};window.PR={combinePrefixPatterns:O,createSimpleLexer:B,registerLangHandler:u,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:C,PR_DECLARATION:"dec",PR_KEYWORD:R,PR_LITERAL:J,PR_NOCODE:V,PR_PLAIN:z,PR_PUNCTUATION:E,PR_SOURCE:P,PR_STRING:A,
PR_TAG:"tag",PR_TYPE:S}})()

BIN
service/JavaService.exe View File


BIN
service/JavaService64.exe View File


+ 1
- 0
service/UninstallService.bat View File

@@ -0,0 +1 @@
javaservice -uninstall gitblit

+ 1
- 0
service/UninstallService64.bat View File

@@ -0,0 +1 @@
javaservice64 -uninstall gitblit

+ 2
- 0
service/installService.bat View File

@@ -0,0 +1,2 @@
set JDK=C:\Program Files\Java\jdk1.6.0_21
JavaService.exe -install gitblit "%JDK%\jre\bin\server\jvm.dll" -Xmx1024M -Djava.class.path=%CD%\gitblit.jar;"%JDK%\lib\tools.jar" -start com.gitblit.Launcher -params --storePassword dosomegit -stop com.gitblit.Launcher -params --stop -out %CD%\logs\stdout.log -err %CD%\logs\stderr.log -current %CD%

+ 2
- 0
service/installService64.bat View File

@@ -0,0 +1,2 @@
set JDK=C:\Program Files\Java\jdk1.6.0_21
JavaService64.exe -install gitblit "%JDK%\jre\bin\server\jvm.dll" -Djava.class.path=%CD%\gitblit.jar;"%JDK%\lib\tools.jar" -start com.gitblit.Launcher -params --storePassword dosomegit -stop com.gitblit.Launcher -params --stop -out %CD%\logs\stdout.log -err %CD%\logs\stderr.log -current %CD%

+ 168
- 0
src/com/gitblit/Build.java View File

@@ -0,0 +1,168 @@
package com.gitblit;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Build {
public static void main(String... args) {
runtime();
compiletime();
}
public static void runtime() {
downloadFromMaven(MavenObject.JCOMMANDER);
downloadFromMaven(MavenObject.JETTY);
downloadFromMaven(MavenObject.SERVLET);
downloadFromMaven(MavenObject.SLF4JAPI);
downloadFromMaven(MavenObject.SLF4LOG4J);
downloadFromMaven(MavenObject.LOG4J);
downloadFromMaven(MavenObject.WICKET);
downloadFromMaven(MavenObject.WICKET_EXT);
downloadFromMaven(MavenObject.WICKET_AUTH_ROLES);
}
public static void compiletime() {
downloadFromMaven(MavenObject.JUNIT);
}
/**
* Download a file from a Maven repository.
*
* @param mo
* the maven object to download.
* @return
*/
private static File downloadFromMaven(MavenObject mo) {
File targetFile = mo.getLocalFile("ext");
if (targetFile.exists()) {
return targetFile;
}
String mavenURL = "http://repo1.maven.org/maven2/" + mo.getRepositoryPath();
if (!targetFile.getAbsoluteFile().getParentFile().exists()) {
boolean success = targetFile.getAbsoluteFile().getParentFile().mkdirs();
if (!success) {
throw new RuntimeException("Failed to create destination folder structure!");
}
}
ByteArrayOutputStream buff = new ByteArrayOutputStream();
try {
System.out.println("Downloading " + mavenURL);
URL url = new URL(mavenURL);
InputStream in = new BufferedInputStream(url.openStream());
long last = System.currentTimeMillis();
int len = 0;
while (true) {
long now = System.currentTimeMillis();
if (now > last + 200) {
System.out.println(" downloaded " + len + " bytes");
last = now;
}
int x = in.read();
len++;
if (x < 0) {
break;
}
buff.write(x);
}
in.close();
} catch (IOException e) {
throw new RuntimeException("Error downloading " + mavenURL + " to " + targetFile, e);
}
byte[] data = buff.toByteArray();
String got = getSHA1(data);
if (mo.sha1 != null && !got.equals(mo.sha1)) {
throw new RuntimeException("SHA1 checksum mismatch; got: " + got);
}
try {
RandomAccessFile ra = new RandomAccessFile(targetFile, "rw");
ra.write(data);
ra.setLength(data.length);
ra.close();
} catch (IOException e) {
throw new RuntimeException("Error writing to file " + targetFile, e);
}
return targetFile;
}
/**
* Generate the SHA1 checksum of a byte array.
*
* @param data
* the byte array
* @return the SHA1 checksum
*/
private static String getSHA1(byte[] data) {
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-1");
byte[] value = md.digest(data);
StringBuilder buff = new StringBuilder(value.length * 2);
for (byte c : value) {
int x = c & 0xff;
buff.append(Integer.toString(x >> 4, 16)).append(Integer.toString(x & 0xf, 16));
}
return buff.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
private static class MavenObject {
public static final MavenObject JCOMMANDER = new MavenObject("jCommander", "com/beust", "jcommander", "1.17", "219a3540f3b27d7cc3b1d91d6ea046cd8723290e");
public static final MavenObject JETTY = new MavenObject("Jetty", "org/eclipse/jetty/aggregate", "jetty-all", "7.2.2.v20101205", "b9b7c812a732721c427e208c54fbb71ca17a2ee1");
public static final MavenObject SERVLET = new MavenObject("Servlet 2.5", "javax/servlet", "servlet-api", "2.5", "5959582d97d8b61f4d154ca9e495aafd16726e34");
public static final MavenObject SLF4JAPI = new MavenObject("SLF4J API", "org/slf4j", "slf4j-api", "1.6.1", "6f3b8a24bf970f17289b234284c94f43eb42f0e4");
public static final MavenObject SLF4LOG4J = new MavenObject("SLF4J LOG4J", "org/slf4j", "slf4j-log4j12", "1.6.1", "bd245d6746cdd4e6203e976e21d597a46f115802");
public static final MavenObject LOG4J = new MavenObject("Apache LOG4J", "log4j", "log4j", "1.2.16", "7999a63bfccbc7c247a9aea10d83d4272bd492c6");
public static final MavenObject WICKET = new MavenObject("Apache Wicket", "org/apache/wicket", "wicket", "1.4.17", "39815e37a6f56465b2d2c3d3017c4f3bf17db50a");
public static final MavenObject WICKET_EXT = new MavenObject("Apache Wicket Extensions", "org/apache/wicket", "wicket-extensions", "1.4.17", "01111d0dbffdc425581b006a43864c22797ce72a");
public static final MavenObject WICKET_AUTH_ROLES = new MavenObject("Apache Wicket Auth Roles", "org/apache/wicket", "wicket-auth-roles", "1.4.17", "86d20ff32f62d3026213ff11a78555da643bc676");
public static final MavenObject JUNIT = new MavenObject("JUnit", "junit", "junit", "3.8.2", "07e4cde26b53a9a0e3fe5b00d1dbbc7cc1d46060");
public final String name;
public final String group;
public final String artifact;
public final String version;
public final String sha1;
private MavenObject(String name, String group, String artifact, String version, String sha1) {
this.name = name;
this.group = group;
this.artifact = artifact;
this.version = version;
this.sha1 = sha1;
}
private String getRepositoryPath() {
return group + "/" + artifact + "/" + version + "/" + artifact + "-" + version + ".jar";
}
private File getLocalFile(String basePath) {
return new File(basePath, artifact + "-" + version + ".jar");
}
@Override
public String toString() {
return name;
}
}
}

+ 12
- 0
src/com/gitblit/Constants.java View File

@@ -0,0 +1,12 @@
package com.gitblit;
public class Constants {
public final static String NAME = "Git:Blit";
public final static String VERSION = "0.11.3";
public static String getRunningVersion() {
return NAME + " v" + VERSION;
}
}

+ 393
- 0
src/com/gitblit/GitBlitServer.java View File

@@ -0,0 +1,393 @@
package com.gitblit;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.PatternLayout;
import org.apache.wicket.protocol.http.ContextParamWebApplicationFactory;
import org.apache.wicket.protocol.http.WicketFilter;
import org.eclipse.jetty.http.security.Constraint;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslConnector;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jgit.http.server.GitServlet;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
import com.gitblit.wicket.GitBlitWebApp;
public class GitBlitServer {
private final static Logger logger = Log.getLogger(GitBlitServer.class.getSimpleName());
private final static String border_star = "***********************************************************";
private static boolean debugMode = false;
public static boolean isDebugMode() {
return debugMode;
}
public static void main(String[] args) {
Params params = new Params();
JCommander jc = new JCommander(params);
try {
jc.parse(args);
if (params.help)
usage(jc, null);
} catch (ParameterException t) {
usage(jc, t);
}
if (params.stop)
stop(params);
else
start(params);
}
private static void usage(JCommander jc, ParameterException t) {
System.out.println(border_star);
System.out.println(Constants.getRunningVersion());
System.out.println(border_star);
System.out.println();
if (t != null) {
System.out.println(t.getMessage());
System.out.println();
}
if (jc != null) {
jc.usage();
System.out.println("\nExample:\n java -server -Xmx1024M -jar go-git-go.jar --repos c:\\git --port 80 --securePort 443");
}
System.exit(0);
}
/**
* Stop Server.
*/
public static void stop(Params params) {
try {
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), params.shutdownPort);
OutputStream out = s.getOutputStream();
System.out.println("Sending Shutdown Request to " + Constants.NAME);
out.write(("\r\n").getBytes());
out.flush();
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Start Server.
*/
private static void start(Params params) {
PatternLayout layout = new PatternLayout(StoredSettings.getString("log4jPattern", "%-5p %d{MM-dd HH:mm:ss.SSS} %-20.20c{1} %m%n"));
org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger();
rootLogger.addAppender(new ConsoleAppender(layout));
logger.info(border_star);
logger.info(Constants.getRunningVersion());
logger.info(border_star);
String osname = System.getProperty("os.name");
String osversion = System.getProperty("os.version");
logger.info("Running on " + osname + " (" + osversion + ")");
if (params.debug) {
logger.warn("DEBUG Mode");
}
// Determine port connectors
List<Connector> connectors = new ArrayList<Connector>();
if (params.port > 0) {
Connector httpConnector = createConnector(params.useNIO, params.port);
connectors.add(httpConnector);
}
if (params.securePort > 0) {
if (new File("keystore").exists()) {
Connector secureConnector = createSSLConnector(params.useNIO, params.securePort, params.storePassword);
connectors.add(secureConnector);
} else {
logger.warn("Failed to find Keystore? Did you run \"makekeystore\"?");
logger.warn("SSL connector DISABLED.");
}
}
// tempDir = Directory where...
// * WebApp is expanded
//
File tempDir = new File(params.temp);
if (tempDir.exists())
deleteRecursively(tempDir);
tempDir.mkdirs();
Server server = new Server();
server.setStopAtShutdown(true);
server.setConnectors(connectors.toArray(new Connector[connectors.size()]));
// Get the execution path of this class
// We use this to set the WAR path.
ProtectionDomain protectionDomain = GitBlitServer.class.getProtectionDomain();
URL location = protectionDomain.getCodeSource().getLocation();
// Root WebApp Context
WebAppContext rootContext = new WebAppContext();
rootContext.setContextPath("/");
rootContext.setServer(server);
rootContext.setWar(location.toExternalForm());
rootContext.setTempDirectory(tempDir);
// Wicket Filter
String wicketPathSpec = "/*";
FilterHolder wicketFilter = new FilterHolder(WicketFilter.class);
wicketFilter.setInitParameter(ContextParamWebApplicationFactory.APP_CLASS_PARAM, GitBlitWebApp.class.getName());
wicketFilter.setInitParameter(WicketFilter.FILTER_MAPPING_PARAM, wicketPathSpec);
rootContext.addFilter(wicketFilter, wicketPathSpec, FilterMapping.DEFAULT);
// GIT Servlet
String gitServletPathSpec = "/git/*";
ServletHolder gitServlet = rootContext.addServlet(GitServlet.class, gitServletPathSpec);
gitServlet.setInitParameter("base-path", params.repositoriesFolder);
gitServlet.setInitParameter("export-all", params.exportAll ? "1" : "0");
String realmUsers = params.realmFile;
// Authentication Realm
Handler handler;
if (realmUsers != null && new File(realmUsers).exists() && params.authenticateAccess) {
List<String> list = StoredSettings.getStrings("gitRoles");
String[] roles;
if (list.size() == 0) {
roles = new String[] { "*" };
} else {
roles = list.toArray(new String[list.size()]);
}
logger.info("Authentication required for GIT access");
logger.info("Setting up realm from " + realmUsers);
HashLoginService loginService = new HashLoginService(Constants.NAME, realmUsers);
Constraint constraint = new Constraint();
constraint.setName("auth");
constraint.setAuthenticate(true);
constraint.setRoles(roles);
ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec(gitServletPathSpec);
mapping.setConstraint(constraint);
ConstraintSecurityHandler security = new ConstraintSecurityHandler();
security.addConstraintMapping(mapping);
for (String role : roles) {
security.addRole(role);
}
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
security.setHandler(rootContext);
handler = security;
} else {
logger.info("Setting up anonymous access");
handler = rootContext;
}
// Set the server's contexts
server.setHandler(handler);
// Start the Server
try {
if (params.shutdownPort > 0) {
Thread shutdownMonitor = new ShutdownMonitorThread(server, params);
shutdownMonitor.start();
}
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(100);
}
}
private static Connector createConnector(boolean useNIO, int port) {
Connector connector;
if (useNIO) {
logger.info("Setting up NIO SelectChannelConnector on port " + port);
SelectChannelConnector nioconn = new SelectChannelConnector();
nioconn.setSoLingerTime(-1);
nioconn.setThreadPool(new QueuedThreadPool(20));
connector = nioconn;
} else {
logger.info("Setting up SocketConnector on port " + port);
SocketConnector sockconn = new SocketConnector();
connector = sockconn;
}
connector.setPort(port);
connector.setMaxIdleTime(30000);
return connector;
}
private static Connector createSSLConnector(boolean useNIO, int port, String password) {
SslConnector connector;
if (useNIO) {
logger.info("Setting up NIO SslSelectChannelConnector on port " + port);
SslSelectChannelConnector ssl = new SslSelectChannelConnector();
ssl.setSoLingerTime(-1);
ssl.setThreadPool(new QueuedThreadPool(20));
connector = ssl;
} else {
logger.info("Setting up NIO SslSocketConnector on port " + port);
SslSocketConnector ssl = new SslSocketConnector();
connector = ssl;
}
connector.setKeystore("keystore");
connector.setPassword(password);
connector.setPort(port);
connector.setMaxIdleTime(30000);
return connector;
}
/**
* Recursively delete a folder and its contents.
*
* @param folder
*/
private static void deleteRecursively(File folder) {
for (File file : folder.listFiles()) {
if (file.isDirectory())
deleteRecursively(file);
else
file.delete();
}
folder.delete();
}
private static class ShutdownMonitorThread extends Thread {
private final ServerSocket socket;
private final Server server;
public ShutdownMonitorThread(Server server, Params params) {
this.server = server;
setDaemon(true);
setName(Constants.NAME + " Shutdown Monitor");
ServerSocket skt = null;
try {
skt = new ServerSocket(params.shutdownPort, 1, InetAddress.getByName("127.0.0.1"));
} catch (Exception e) {
logger.warn(e);
}
socket = skt;
}
@Override
public void run() {
logger.info("Shutdown Monitor listening on port " + socket.getLocalPort());
Socket accept;
try {
accept = socket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
reader.readLine();
logger.info(border_star);
logger.info("Stopping " + Constants.NAME);
logger.info(border_star);
server.stop();
server.setStopAtShutdown(false);
accept.close();
socket.close();
} catch (Exception e) {
logger.warn("Failed to shutdown Jetty", e);
}
}
}
@Parameters(separators = " ")
private static class Params {
/*
* Server parameters
*/
@Parameter(names = { "-h", "--help" }, description = "Show this help")
public Boolean help = false;
@Parameter(names = { "--stop" }, description = "Stop Server")
public Boolean stop = false;
@Parameter(names = { "--temp" }, description = "Server temp folder")
public String temp = StoredSettings.getString("tempFolder", "temp");
@Parameter(names = { "--debug" }, description = "Run server in DEBUG mode")
public Boolean debug = StoredSettings.getBoolean("debug", false);
/*
* GIT Servlet Parameters
*/
@Parameter(names = { "--repos" }, description = "GIT Repositories Folder")
public String repositoriesFolder = StoredSettings.getString("repositoriesFolder", "repos");
@Parameter(names = { "--exportAll" }, description = "Export All Found Repositories")
public Boolean exportAll = StoredSettings.getBoolean("exportAll", true);
/*
* Authentication Parameters
*/
@Parameter(names = { "--authenticateAccess" }, description = "Authenticate GIT access")
public Boolean authenticateAccess = StoredSettings.getBoolean("authenticateAccess", true);
@Parameter(names = { "--realm" }, description = "Users Realm Hash File")
public String realmFile = StoredSettings.getString("realmFile", "users.properties");
/*
* JETTY Parameters
*/
@Parameter(names = { "--nio" }, description = "Use NIO Connector else use Socket Connector.")
public Boolean useNIO = StoredSettings.getBoolean("useNio", true);
@Parameter(names = "--port", description = "HTTP port for to serve. (port <= 0 will disable this connector)")
public Integer port = StoredSettings.getInteger("httpPort", 80);
@Parameter(names = "--securePort", description = "HTTPS port to serve. (port <= 0 will disable this connector)")
public Integer securePort = StoredSettings.getInteger("httpsPort", 443);
@Parameter(names = "--storePassword", description = "Password for SSL (https) keystore.")
public String storePassword = StoredSettings.getString("storePassword", "");
@Parameter(names = "--shutdownPort", description = "Port for Shutdown Monitor to listen on. (port <= 0 will disable this monitor)")
public Integer shutdownPort = StoredSettings.getInteger("shutdownPort", 8081);
}
}

+ 117
- 0
src/com/gitblit/Launcher.java View File

@@ -0,0 +1,117 @@
package com.gitblit;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Launch helper class that adds all jars found in the local "lib" folder and
* then calls the application main. Using this technique we do not have to
* specify a classpath and we can dynamically add jars to the distribution.
*
*/
public class Launcher {
public final static boolean debug = false;
public static void main(String[] args) {
if (debug)
System.out.println("jcp=" + System.getProperty("java.class.path"));
ProtectionDomain protectionDomain = Launcher.class.getProtectionDomain();
final String launchJar = protectionDomain.getCodeSource().getLocation().toExternalForm();
if (debug)
System.out.println("launcher=" + launchJar);
Build.runtime();
// Load the JARs in the lib and ext folder
String[] folders = new String[] { "lib", "ext" };
List<File> jars = new ArrayList<File>();
for (String folder : folders) {
if (folder == null)
continue;
File libFolder = new File(folder);
if (!libFolder.exists())
continue;
try {
libFolder = libFolder.getCanonicalFile();
} catch (IOException iox) {
}
jars.addAll(findJars(libFolder));
}
if (jars.size() == 0) {
for (String folder : folders) {
File libFolder = new File(folder);
System.err.println("Failed to find any JARs in " + libFolder.getPath());
}
System.exit(-1);
} else {
for (File jar : jars) {
try {
addJarFile(jar);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
// Start Server
GitBlitServer.main(args);
}
public static List<File> findJars(File folder) {
List<File> jars = new ArrayList<File>();
if (folder.exists()) {
File[] libs = folder.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return !file.isDirectory() && file.getName().toLowerCase().endsWith(".jar");
}
});
if (libs != null && libs.length > 0) {
jars.addAll(Arrays.asList(libs));
if (debug) {
for (File jar : jars)
System.out.println("found " + jar);
}
}
}
return jars;
}
/**
* Parameters of the method to add an URL to the System classes.
*/
private static final Class<?>[] parameters = new Class[] { URL.class };
/**
* Adds a file to the classpath
*
* @param f
* the file to be added
* @throws IOException
*/
public static void addJarFile(File f) throws IOException {
URL u = f.toURI().toURL();
if (debug)
System.out.println("load=" + u.toExternalForm());
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<?> sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[] { u });
} catch (Throwable t) {
throw new IOException("Error, could not add " + f.getPath() + " to system classloader", t);
}
}
}

+ 51
- 0
src/com/gitblit/MakeRepository.java View File

@@ -0,0 +1,51 @@
package com.gitblit;
import java.io.File;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.InitCommand;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
public class MakeRepository {
public static void main(String... args) throws Exception {
Params params = new Params();
JCommander jc = new JCommander(params);
try {
jc.parse(args);
if (params.help)
jc.usage();
} catch (ParameterException t) {
jc.usage();
}
File directory = new File(params.create);
InitCommand init = new InitCommand();
init.setDirectory(directory);
init.setBare(true);
Git git = init.call();
git.getRepository().close();
System.out.println("GIT repository " + directory.getCanonicalPath() + " created.");
}
@Parameters(separators = " ")
private static class Params {
/*
* Help/Usage
*/
@Parameter(names = { "-h", "--help" }, description = "Show this help")
public Boolean help = false;
/*
* Repository to Create
*/
@Parameter(names = { "--create" }, description = "GIT Repository to Create", required = true)
public String create = "";
}
}

+ 130
- 0
src/com/gitblit/StoredSettings.java View File

@@ -0,0 +1,130 @@
package com.gitblit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Reads settings file.
*
*/
public class StoredSettings {
private static Properties properties = new Properties();
private static long lastread = 0;
private static final Logger logger = LoggerFactory.getLogger(StoredSettings.class);
public static List<String> getAllKeys(String startingWith) {
startingWith = startingWith.toLowerCase();
List<String> keys = new ArrayList<String>();
Properties props = read();
for (Object o : props.keySet()) {
String key = o.toString().toLowerCase();
if (key.startsWith(startingWith)) {
keys.add(key);
}
}
return keys;
}
public static boolean getBoolean(String name, boolean defaultValue) {
Properties props = read();
if (props.containsKey(name)) {
try {
String value = props.getProperty(name);
if (value != null && value.trim().length() > 0) {
return Boolean.parseBoolean(value);
}
} catch (Exception e) {
logger.warn("No override setting for " + name + " using default of " + defaultValue);
}
}
return defaultValue;
}
public static int getInteger(String name, int defaultValue) {
Properties props = read();
if (props.containsKey(name)) {
try {
String value = props.getProperty(name);
if (value != null && value.trim().length() > 0) {
return Integer.parseInt(value);
}
} catch (Exception e) {
logger.warn("No override setting for " + name + " using default of " + defaultValue);
}
}
return defaultValue;
}
public static String getString(String name, String defaultValue) {
Properties props = read();
if (props.containsKey(name)) {
try {
String value = props.getProperty(name);
if (value != null) {
return value;
}
} catch (Exception e) {
logger.warn("No override setting for " + name + " using default of " + defaultValue);
}
}
return defaultValue;
}
public static List<String> getStrings(String name) {
return getStrings(name, " ");
}
public static List<String> getStringsFromValue(String value) {
return getStringsFromValue(value, " ");
}
public static List<String> getStrings(String name, String separator) {
List<String> strings = new ArrayList<String>();
Properties props = read();
if (props.containsKey(name)) {
String value = props.getProperty(name);
strings = getStringsFromValue(value, separator);
}
return strings;
}
public static List<String> getStringsFromValue(String value, String separator) {
List<String> strings = new ArrayList<String>();
try {
String[] chunks = value.split(separator);
for (String chunk : chunks) {
chunk = chunk.trim();
if (chunk.length() > 0) {
strings.add(chunk);
}
}
} catch (Exception e) {
}
return strings;
}
private static synchronized Properties read() {
File file = new File("gitblit.properties");
if (file.exists() && (file.lastModified() > lastread)) {
try {
properties = new Properties();
properties.load(new FileInputStream("gitblit.properties"));
lastread = file.lastModified();
} catch (FileNotFoundException f) {
} catch (Throwable t) {
t.printStackTrace();
}
}
return properties;
}
}

+ 71
- 0
src/com/gitblit/tests/JGitUtilsTest.java View File

@@ -0,0 +1,71 @@
package com.gitblit.tests;
import java.io.File;
import java.util.Date;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.storage.file.FileRepository;
import com.gitblit.utils.JGitUtils;
public class JGitUtilsTest extends TestCase {
private File repositoriesFolder = new File("c:/projects/git");
private boolean exportAll = true;
private boolean readNested = true;
private List<String> getRepositories() {
return JGitUtils.getRepositoryList(repositoriesFolder, exportAll, readNested);
}
private Repository getRepository() throws Exception {
return new FileRepository(new File(repositoriesFolder, getRepositories().get(0)) + "/" + Constants.DOT_GIT);
}
public void testFindRepositories() {
List<String> list = getRepositories();
assertTrue("No repositories found in " + repositoriesFolder, list.size() > 0);
}
public void testOpenRepository() throws Exception {
Repository r = getRepository();
r.close();
assertTrue("Could not find repository!", r != null);
}
public void testLastChangeRepository() throws Exception {
Repository r = getRepository();
Date date = JGitUtils.getLastChange(r);
r.close();
assertTrue("Could not get last repository change date!", date != null);
}
public void testRetrieveRevObject() throws Exception {
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, Constants.HEAD);
RevTree tree = commit.getTree();
RevObject object = JGitUtils.getRevObject(r, tree, "AUTHORS");
r.close();
assertTrue("Object is null!", object != null);
}
public void testRetrieveStringContent() throws Exception {
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, Constants.HEAD);
RevTree tree = commit.getTree();
RevBlob blob = (RevBlob) JGitUtils.getRevObject(r, tree, "AUTHORS");
String content = JGitUtils.getRawContentAsString(r, blob);
r.close();
assertTrue("Content is null!", content != null);
}
}

+ 82
- 0
src/com/gitblit/utils/ByteFormat.java View File

@@ -0,0 +1,82 @@
/*
* Copyright 2011 Squeal Group. Licensed under the Eclipse Public License,
* Version 1.0 (http://www.eclipse.org/legal/epl-v10.html).
* Initial Developer: Squeal Group
*/
package com.gitblit.utils;

import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;

/**
* A formatter for formatting byte sizes. For example, formatting 12345 byes
* results in "12.1 K" and 1234567 results in "1.18 MB".
*
*/
public class ByteFormat extends Format {

private static final long serialVersionUID = 1L;

public ByteFormat() {
}

// Implemented from the Format class

/**
* Formats a long which represent a number of bytes.
*/
public String format(long bytes) {
return format(Long.valueOf(bytes));
}

/**
* Formats a long which represent a number of kilobytes.
*/
public String formatKB(long kilobytes) {
return format(Long.valueOf(kilobytes * 1024));
}

/**
* Format the given object (must be a Long).
*
* @param obj
* assumed to be the number of bytes as a Long.
* @param buf
* the StringBuffer to append to.
* @param pos
* @return A formatted string representing the given bytes in more
* human-readable form.
*/
public StringBuffer format(Object obj, StringBuffer buf, FieldPosition pos) {
if (obj instanceof Long) {
long numBytes = ((Long) obj).longValue();
if (numBytes < 1024) {
DecimalFormat formatter = new DecimalFormat("#,##0");
buf.append(formatter.format((double) numBytes)).append(" b");
} else if (numBytes < 1024 * 1024) {
DecimalFormat formatter = new DecimalFormat("#,##0.0");
buf.append(formatter.format((double) numBytes / 1024.0)).append(" KB");
} else if (numBytes < 1024 * 1024 * 1024) {
DecimalFormat formatter = new DecimalFormat("#,##0.0");
buf.append(formatter.format((double) numBytes / (1024.0 * 1024.0))).append(" MB");
} else {
DecimalFormat formatter = new DecimalFormat("#,##0.0");
buf.append(formatter.format((double) numBytes / (1024.0 * 1024.0 * 1024.0))).append(" GB");
}
}
return buf;
}

/**
* In this implementation, returns null always.
*
* @param source
* @param pos
* @return returns null in this implementation.
*/
public Object parseObject(String source, ParsePosition pos) {
return null;
}
}

+ 430
- 0
src/com/gitblit/utils/JGitUtils.java View File

@@ -0,0 +1,430 @@
package com.gitblit.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.wicket.models.PathModel;
import com.gitblit.wicket.models.RefModel;
public class JGitUtils {
/** Prefix for notes refs */
public static final String R_NOTES = "refs/notes/";
/** Standard notes ref */
public static final String R_NOTES_COMMITS = R_NOTES + "commits";
private final static Logger LOGGER = LoggerFactory.getLogger(JGitUtils.class);
public static List<String> getRepositoryList(File repositoriesFolder, boolean exportAll, boolean readNested) {
List<String> list = new ArrayList<String>();
list.addAll(getNestedRepositories(repositoriesFolder, repositoriesFolder, exportAll, readNested));
Collections.sort(list);
return list;
}
public static List<String> getNestedRepositories(File repositoriesFolder, File folder, boolean exportAll, boolean readNested) {
String basefile = repositoriesFolder.getAbsolutePath();
List<String> list = new ArrayList<String>();
for (File file : folder.listFiles()) {
if (file.isDirectory() && !file.getName().equalsIgnoreCase(Constants.DOT_GIT)) {
// if this is a git repository add it to the list
File gitFolder = new File(file, Constants.DOT_GIT);
boolean isGitRepository = gitFolder.exists() && gitFolder.isDirectory();
boolean exportRepository = isGitRepository && (exportAll || new File(gitFolder, "git-daemon-export-ok").exists());
if (exportRepository) {
// determine repository name relative to repositories folder
String filename = file.getAbsolutePath();
String repo = filename.substring(basefile.length()).replace('\\', '/');
if (repo.charAt(0) == '/') {
repo = repo.substring(1);
}
list.add(repo);
}
// look for nested repositories
if (readNested) {
list.addAll(getNestedRepositories(repositoriesFolder, file, exportAll, readNested));
}
}
}
return list;
}
public static Date getLastChange(Repository r) {
RevCommit commit = getCommit(r, Constants.HEAD);
return getCommitDate(commit);
}
public static RevCommit getCommit(Repository r, String commitId) {
RevCommit commit = null;
try {
ObjectId objectId = r.resolve(commitId);
RevWalk walk = new RevWalk(r);
RevCommit rev = walk.parseCommit(objectId);
commit = rev;
walk.dispose();
} catch (Throwable t) {
LOGGER.error("Failed to determine last change", t);
}
return commit;
}
public static Map<ObjectId, List<String>> getAllRefs(Repository r) {
Map<ObjectId, List<String>> refs = new HashMap<ObjectId, List<String>>();
Map<AnyObjectId, Set<Ref>> allRefs = r.getAllRefsByPeeledObjectId();
for (AnyObjectId id : allRefs.keySet()) {
List<String> list = new ArrayList<String>();
for (Ref setRef : allRefs.get(id)) {
String name = setRef.getName();
list.add(name);
}
refs.put(id.toObjectId(), list);
}
return refs;
}
public static Map<ObjectId, List<String>> getRefs(Repository r, String baseRef) {
Map<ObjectId, List<String>> refs = new HashMap<ObjectId, List<String>>();
Map<AnyObjectId, Set<Ref>> allRefs = r.getAllRefsByPeeledObjectId();
for (AnyObjectId id : allRefs.keySet()) {
List<String> list = new ArrayList<String>();
for (Ref setRef : allRefs.get(id)) {
String name = setRef.getName();
if (name.startsWith(baseRef)) {
list.add(name);
}
}
refs.put(id.toObjectId(), list);
}
return refs;
}
/**
* Lookup an entry stored in a tree, failing if not present.
*
* @param tree
* the tree to search.
* @param path
* the path to find the entry of.
* @return the parsed object entry at this path
* @throws Exception
*/
public static RevObject getRevObject(Repository r, final RevTree tree, final String path) {
RevObject ro = null;
RevWalk rw = new RevWalk(r);
TreeWalk tw = new TreeWalk(r);
tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path)));
try {
tw.reset(tree);
while (tw.next()) {
if (tw.isSubtree() && !path.equals(tw.getPathString())) {
tw.enterSubtree();
continue;
}
ObjectId entid = tw.getObjectId(0);
FileMode entmode = tw.getFileMode(0);
ro = rw.lookupAny(entid, entmode.getObjectType());
rw.parseBody(ro);
}
} catch (Throwable t) {
LOGGER.error("Can't find " + path + " in tree " + tree.name(), t);
} finally {
if (rw != null) {
rw.dispose();
}
}
return ro;
}
public static byte[] getRawContent(Repository r, RevBlob blob) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ObjectLoader ldr = r.open(blob.getId(), Constants.OBJ_BLOB);
byte[] tmp = new byte[1024];
InputStream in = ldr.openStream();
int n;
while ((n = in.read(tmp)) > 0) {
os.write(tmp, 0, n);
}
in.close();
} catch (Throwable t) {
LOGGER.error("Failed to read raw content", t);
}
return os.toByteArray();
}
public static String getRawContentAsString(Repository r, RevBlob blob) {
return new String(getRawContent(r, blob));
}
public static String getRawContentAsString(Repository r, RevCommit commit, String blobPath) {
RevObject obj = getRevObject(r, commit.getTree(), blobPath);
return new String(getRawContent(r, (RevBlob) obj));
}
public static List<PathModel> getFilesInPath(Repository r, String basePath, String commitId) {
RevCommit commit = getCommit(r, commitId);
return getFilesInPath(r, basePath, commit);
}
public static List<PathModel> getFilesInPath(Repository r, String basePath, RevCommit commit) {
List<PathModel> list = new ArrayList<PathModel>();
final TreeWalk walk = new TreeWalk(r);
try {
walk.addTree(commit.getTree());
if (basePath != null && basePath.length() > 0) {
PathFilter f = PathFilter.create(basePath);
walk.setFilter(f);
walk.setRecursive(false);
boolean foundFolder = false;
while (walk.next()) {
if (!foundFolder && walk.isSubtree()) {
walk.enterSubtree();
}
if (walk.getPathString().equals(basePath)) {
foundFolder = true;
continue;
}
if (foundFolder) {
list.add(getPathModel(walk, basePath, commit));
}
}
} else {
walk.setRecursive(false);
while (walk.next()) {
list.add(getPathModel(walk, null, commit));
}
}
} catch (IOException e) {
LOGGER.error("Failed to get files for commit " + commit.getName(), e);
} finally {
walk.release();
}
Collections.sort(list);
return list;
}
public static List<PathModel> getCommitChangedPaths(Repository r, String commitId) {
RevCommit commit = getCommit(r, commitId);
return getCommitChangedPaths(r, commit);
}
public static List<PathModel> getCommitChangedPaths(Repository r, RevCommit commit) {
List<PathModel> list = new ArrayList<PathModel>();
final TreeWalk walk = new TreeWalk(r);
walk.setRecursive(false);
try {
walk.addTree(commit.getTree());
while (walk.next()) {
list.add(getPathModel(walk, null, commit));
}
} catch (IOException e) {
LOGGER.error("Failed to get files for commit " + commit.getName(), e);
} finally {
if (walk != null) {
walk.release();
}
}
return list;
}
private static PathModel getPathModel(TreeWalk walk, String basePath, RevCommit commit) {
String name;
long size = 0;
if (basePath == null) {
name = walk.getPathString();
} else {
try {
name = walk.getPathString().substring(basePath.length() + 1);
} catch (Throwable t) {
name = walk.getPathString();
}
}
try {
if (!walk.isSubtree()) {
size = walk.getObjectReader().getObjectSize(walk.getObjectId(0), Constants.OBJ_BLOB);
}
} catch (Throwable t) {
LOGGER.error("Failed to retrieve blobl size", t);
}
return new PathModel(name, walk.getPathString(), size, walk.getFileMode(0).getBits(), commit.getName());
}
public static String getPermissionsFromMode(int mode) {
if (FileMode.TREE.equals(mode)) {
return "drwxr-xr-x";
} else if (FileMode.REGULAR_FILE.equals(mode)) {
return "-rw-r--r--";
} else if (FileMode.EXECUTABLE_FILE.equals(mode)) {
return "-rwxr-xr-x";
} else if (FileMode.SYMLINK.equals(mode)) {
// FIXME symlink permissions
return "symlink";
} else if (FileMode.GITLINK.equals(mode)) {
// FIXME gitlink permissions
return "gitlink";
} else if (FileMode.MISSING.equals(mode)) {
// FIXME missing permissions
return "missing";
}
return "" + mode;
}
public static boolean isTreeFromMode(int mode) {
return FileMode.TREE.equals(mode);
}
public static List<RevCommit> getRevLog(Repository r, int maxCount) {
List<RevCommit> list = new ArrayList<RevCommit>();
try {
Git git = new Git(r);
Iterable<RevCommit> revlog = git.log().call();
for (RevCommit rev : revlog) {
list.add(rev);
if (maxCount > 0 && list.size() == maxCount) {
break;
}
}
} catch (Throwable t) {
LOGGER.error("Failed to determine last change", t);
}
return list;
}
public static List<RefModel> getTags(Repository r, int maxCount) {
return getRefs(r, Constants.R_TAGS, maxCount);
}
public static List<RefModel> getHeads(Repository r, int maxCount) {
return getRefs(r, Constants.R_HEADS, maxCount);
}
public static List<RefModel> getRefs(Repository r, String refs, int maxCount) {
List<RefModel> list = new ArrayList<RefModel>();
try {
Map<String, Ref> map = r.getRefDatabase().getRefs(refs);
for (String name : map.keySet()) {
Ref ref = map.get(name);
RevCommit commit = getCommit(r, ref.getObjectId().getName());
list.add(new RefModel(name, ref, commit));
}
Collections.sort(list);
Collections.reverse(list);
if (maxCount > 0 && list.size() > maxCount) {
list = list.subList(0, maxCount);
}
} catch (IOException e) {
LOGGER.error("Failed to retrieve " + refs, e);
}
return list;
}
public static Ref getRef(Repository r, String id) {
try {
Map<String, Ref> map = r.getRefDatabase().getRefs(id);
for (String name : map.keySet()) {
return map.get(name);
}
} catch (IOException e) {
LOGGER.error("Failed to retrieve ref " + id, e);
}
return null;
}
public static Date getCommitDate(RevCommit commit) {
return new Date(commit.getCommitTime() * 1000l);
}
public static String getDisplayName(PersonIdent person) {
final StringBuilder r = new StringBuilder();
r.append(person.getName());
r.append(" <");
r.append(person.getEmailAddress());
r.append(">");
return r.toString();
}
public static String getRepositoryDescription(Repository r) {
File dir = r.getDirectory();
if (dir.exists()) {
File description = new File(dir, "description");
if (description.exists() && description.length() > 0) {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(description, "r");
byte[] buffer = new byte[(int) description.length()];
raf.readFully(buffer);
return new String(buffer);
} catch (Throwable t) {
} finally {
try {
raf.close();
} catch (Throwable t) {
}
}
}
}
return "";
}
public static String getRepositoryOwner(Repository r) {
StoredConfig c = readConfig(r);
if (c == null) {
return "";
}
String o = c.getString("gitweb", null, "owner");
return o == null ? "" : o;
}
private static StoredConfig readConfig(Repository r) {
StoredConfig c = r.getConfig();
if (c != null) {
try {
c.load();
} catch (ConfigInvalidException cex) {
LOGGER.error("Repository configuration is invalid!", cex);
} catch (IOException cex) {
LOGGER.error("Could not open repository configuration!", cex);
}
return c;
}
return null;
}
}

+ 119
- 0
src/com/gitblit/utils/Utils.java View File

@@ -0,0 +1,119 @@
package com.gitblit.utils;
import java.util.Date;
public class Utils {
private final static long min = 1000 * 60l;
private final static long halfhour = min * 30l;
private final static long onehour = halfhour * 2;
private final static long oneday = onehour * 24l;
@SuppressWarnings("deprecation")
public static boolean isToday(Date date) {
Date now = new Date();
return now.getDate() == date.getDate() && now.getMonth() == date.getMonth() && now.getYear() == date.getYear();
}
@SuppressWarnings("deprecation")
public static boolean isYesterday(Date date) {
Date now = new Date();
return now.getDate() == (date.getDate() + 1) && now.getMonth() == date.getMonth() && now.getYear() == date.getYear();
}
public static int minutesAgo(Date date, long endTime, boolean roundup) {
long diff = endTime - date.getTime();
int mins = (int) (diff / min);
if (roundup && (diff % min) >= 30)
mins++;
return mins;
}
public static int minutesAgo(Date date, boolean roundup) {
return minutesAgo(date, System.currentTimeMillis(), roundup);
}
public static int hoursAgo(Date date, boolean roundup) {
long diff = System.currentTimeMillis() - date.getTime();
int hours = (int) (diff / onehour);
if (roundup && (diff % onehour) >= halfhour)
hours++;
return hours;
}
public static int daysAgo(Date date, boolean roundup) {
long diff = System.currentTimeMillis() - date.getTime();
int days = (int) (diff / oneday);
if (roundup && (diff % oneday) > 0)
days++;
return days;
}
public static String timeAgo(Date date) {
return timeAgo(date, false);
}
public static String timeAgoCss(Date date) {
return timeAgo(date, true);
}
private static String timeAgo(Date date, boolean css) {
String ago = null;
if (isToday(date) || isYesterday(date)) {
int mins = minutesAgo(date, true);
if (mins > 120) {
if (css) {
return "age1";
}
int hours = hoursAgo(date, true);
if (hours > 23) {
ago = "yesterday";
} else {
ago = hours + " hour" + (hours > 1 ? "s" : "") + " ago";
}
} else {
if (css) {
return "age0";
}
ago = mins + " min" + (mins > 1 ? "s" : "") + " ago";
}
} else {
if (css) {
return "age2";
}
int days = daysAgo(date, true);
if (days < 365) {
if (days <= 30) {
ago = days + " day" + (days > 1 ? "s" : "") + " ago";
} else if (days <= 90) {
int weeks = days / 7;
if (weeks == 12)
ago = "3 months ago";
else
ago = weeks + " weeks ago";
} else if (days > 90) {
int months = days / 30;
int weeks = (days % 30) / 7;
if (weeks >= 2)
months++;
ago = months + " month" + (months > 1 ? "s" : "") + " ago";
} else
ago = days + " day" + (days > 1 ? "s" : "") + " ago";
} else if (days == 365) {
ago = "1 year ago";
} else {
int yr = days / 365;
days = days % 365;
int months = (yr * 12) + (days / 30);
if (months > 23) {
ago = yr + " years ago";
} else {
ago = months + " months ago";
}
}
}
return ago;
}
}

+ 69
- 0
src/com/gitblit/wicket/BasePage.java View File

@@ -0,0 +1,69 @@
package com.gitblit.wicket;
import java.util.Date;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.utils.Utils;
public abstract class BasePage extends WebPage {
Logger logger = LoggerFactory.getLogger(BasePage.class);
public BasePage() {
super();
}
public BasePage(PageParameters params) {
super(params);
}
protected Label createAuthorLabel(String wicketId, String author) {
Label label = new Label(wicketId, author);
WicketUtils.setHtmlTitle(label, author);
return label;
}
protected Label createDateLabel(String wicketId, Date date) {
Label label = new Label(wicketId, GitBlitWebSession.get().formatDate(date));
WicketUtils.setCssClass(label, Utils.timeAgoCss(date));
WicketUtils.setHtmlTitle(label, Utils.timeAgo(date));
return label;
}
protected Label createShortlogDateLabel(String wicketId, Date date) {
String dateString = GitBlitWebSession.get().formatDate(date);
String title = Utils.timeAgo(date);
if ((System.currentTimeMillis() - date.getTime()) < 10 * 24 * 60 * 60 * 1000l) {
dateString = title;
title = GitBlitWebSession.get().formatDate(date);
}
Label label = new Label(wicketId, dateString);
WicketUtils.setCssClass(label, Utils.timeAgoCss(date));
WicketUtils.setHtmlTitle(label, title);
return label;
}
protected void setAlternatingBackground(Component c, int i) {
String clazz = i % 2 == 0 ? "dark" : "light";
WicketUtils.setCssClass(c, clazz);
}
protected String trimShortLog(String string) {
if (string.length() > 60) {
return string.substring(0, 60) + "...";
}
return string;
}
public void error(String message, Throwable t) {
super.error(message);
logger.error(message, t);
}
}

+ 143
- 0
src/com/gitblit/wicket/GitBlitWebApp.java View File

@@ -0,0 +1,143 @@
package com.gitblit.wicket;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.Application;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.Response;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.request.urlcompressing.UrlCompressingWebRequestProcessor;
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
import org.apache.wicket.request.IRequestCycleProcessor;
import org.apache.wicket.request.target.coding.MixedParamUrlCodingStrategy;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.http.server.resolver.FileResolver;
import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.GitBlitServer;
import com.gitblit.StoredSettings;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.models.RepositoryModel;
import com.gitblit.wicket.pages.BlobPage;
import com.gitblit.wicket.pages.CommitPage;
import com.gitblit.wicket.pages.HeadsPage;
import com.gitblit.wicket.pages.LogPage;
import com.gitblit.wicket.pages.RepositoriesPage;
import com.gitblit.wicket.pages.ShortLogPage;
import com.gitblit.wicket.pages.SummaryPage;
import com.gitblit.wicket.pages.TagPage;
import com.gitblit.wicket.pages.TagsPage;
import com.gitblit.wicket.pages.TreePage;
public class GitBlitWebApp extends WebApplication {
public static int PAGING_ITEM_COUNT = 50;
Logger logger = LoggerFactory.getLogger(GitBlitWebApp.class);
FileResolver repositoryResolver;
private File repositories;
private boolean exportAll;
@Override
public void init() {
super.init();
// Grab Browser info (like timezone, etc)
getRequestCycleSettings().setGatherExtendedBrowserInfo(true);
// setup the url paths
mount(new MixedParamUrlCodingStrategy("/summary", SummaryPage.class, new String[] { "p" }));
mount(new MixedParamUrlCodingStrategy("/shortlog", ShortLogPage.class, new String[] { "p", "h" }));
mount(new MixedParamUrlCodingStrategy("/log", LogPage.class, new String[] { "p", "h" }));
mount(new MixedParamUrlCodingStrategy("/tags", TagsPage.class, new String[] { "p" }));
mount(new MixedParamUrlCodingStrategy("/heads", HeadsPage.class, new String[] { "p" }));
mount(new MixedParamUrlCodingStrategy("/commit", CommitPage.class, new String[] { "p", "h" }));
mount(new MixedParamUrlCodingStrategy("/tag", TagPage.class, new String[] { "p", "h" }));
mount(new MixedParamUrlCodingStrategy("/tree", TreePage.class, new String[] { "p", "h", "f" }));
mount(new MixedParamUrlCodingStrategy("/blob", BlobPage.class, new String[] { "p", "h", "f" }));
repositories = new File(StoredSettings.getString("repositoriesFolder", "repos"));
exportAll = StoredSettings.getBoolean("exportAll", true);
repositoryResolver = new FileResolver(repositories, exportAll);
}
@Override
public Class<? extends Page> getHomePage() {
return RepositoriesPage.class;
}
@Override
public final Session newSession(Request request, Response response) {
return new GitBlitWebSession(request);
}
@Override
protected final IRequestCycleProcessor newRequestCycleProcessor() {
return new UrlCompressingWebRequestProcessor();
}
@Override
public final String getConfigurationType() {
if (GitBlitServer.isDebugMode())
return Application.DEVELOPMENT;
return Application.DEPLOYMENT;
}
public List<String> getRepositoryList() {
return JGitUtils.getRepositoryList(repositories, exportAll, StoredSettings.getBoolean("nestedRepositories", true));
}
public List<RepositoryModel> getRepositories(Request request) {
List<String> list = getRepositoryList();
ServletWebRequest servletWebRequest = (ServletWebRequest) request;
HttpServletRequest req = servletWebRequest.getHttpServletRequest();
List<RepositoryModel> repositories = new ArrayList<RepositoryModel>();
for (String repo : list) {
Repository r = getRepository(req, repo);
String description = JGitUtils.getRepositoryDescription(r);
String owner = JGitUtils.getRepositoryOwner(r);
Date lastchange = JGitUtils.getLastChange(r);
r.close();
repositories.add(new RepositoryModel(repo, description, owner, lastchange));
}
return repositories;
}
public Repository getRepository(HttpServletRequest req, String repositoryName) {
Repository r = null;
try {
r = repositoryResolver.open(req, repositoryName);
} catch (RepositoryNotFoundException e) {
r = null;
logger.error("Failed to find repository " + repositoryName);
e.printStackTrace();
} catch (ServiceNotEnabledException e) {
r = null;
e.printStackTrace();
}
return r;
}
public String getCloneUrl(String repositoryName) {
return StoredSettings.getString("cloneUrl", "https://localhost/git/") + repositoryName;
}
public static GitBlitWebApp get() {
return (GitBlitWebApp) WebApplication.get();
}
}

+ 74
- 0
src/com/gitblit/wicket/GitBlitWebSession.java View File

@@ -0,0 +1,74 @@
package com.gitblit.wicket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.apache.wicket.Request;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.protocol.http.request.WebClientInfo;
import com.gitblit.StoredSettings;
public final class GitBlitWebSession extends WebSession {
private static final long serialVersionUID = 1L;
protected TimeZone timezone = null;
public GitBlitWebSession(Request request) {
super(request);
}
public void invalidate() {
super.invalidate();
}
public TimeZone getTimezone() {
if (timezone == null) {
timezone = ((WebClientInfo) getClientInfo()).getProperties().getTimeZone();
}
// use server timezone if we can't determine the client timezone
if (timezone == null) {
timezone = TimeZone.getDefault();
}
return timezone;
}
public String formatTime(Date date) {
DateFormat df = new SimpleDateFormat(StoredSettings.getString("timestampFormat", "h:mm a"));
df.setTimeZone(getTimezone());
return df.format(date);
}
public String formatDate(Date date) {
DateFormat df = new SimpleDateFormat(StoredSettings.getString("datestampShortFormat", "MM/dd/yy"));
df.setTimeZone(getTimezone());
return df.format(date);
}
public String formatDateLong(Date date) {
DateFormat df = new SimpleDateFormat(StoredSettings.getString("datestampLongFormat", "EEEE, MMMM d, yyyy"));
df.setTimeZone(getTimezone());
return df.format(date);
}
public String formatDateTime(Date date) {
DateFormat df = new SimpleDateFormat(StoredSettings.getString("datetimestampShortFormat", "MM/dd/yy h:mm a"));
df.setTimeZone(getTimezone());
return df.format(date);
}
public String formatDateTimeLong(Date date) {
DateFormat df = new SimpleDateFormat(StoredSettings.getString("datetimestampLongFormat", "EEEE, MMMM d, yyyy h:mm a"));
df.setTimeZone(getTimezone());
return df.format(date);
}
public static GitBlitWebSession get() {
return (GitBlitWebSession) Session.get();
}
}

+ 6
- 0
src/com/gitblit/wicket/LinkPanel.html View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<a href="#" wicket:id="link"><span wicket:id="label">link</span></a>
</wicket:panel>
</html>

+ 44
- 0
src/com/gitblit/wicket/LinkPanel.java View File

@@ -0,0 +1,44 @@
package com.gitblit.wicket;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
public class LinkPanel extends Panel {
private static final long serialVersionUID = 1L;
private IModel<String> labelModel = new Model<String>();
@SuppressWarnings({ "unchecked", "rawtypes" })
public LinkPanel(String wicketId, final String linkCssClass, String label, Class<? extends WebPage> clazz, PageParameters parameters) {
super(wicketId);
Link<?> link = null;
if (parameters == null) {
link = new BookmarkablePageLink("link", clazz);
} else {
link = new BookmarkablePageLink("link", clazz, parameters);
}
if (linkCssClass != null) {
link.add(new AttributeModifier("class", true, new AbstractReadOnlyModel<String>() {
private static final long serialVersionUID = 1L;
@Override
public String getObject() {
return linkCssClass;
}
}));
}
labelModel.setObject(label);
link.add(new Label("label", labelModel));
add(link);
}
}

+ 118
- 0
src/com/gitblit/wicket/RepositoryPage.java View File

@@ -0,0 +1,118 @@
package com.gitblit.wicket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.StoredSettings;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.pages.RepositoriesPage;
import com.gitblit.wicket.panels.PageFooter;
import com.gitblit.wicket.panels.PageHeader;
import com.gitblit.wicket.panels.PageLinksPanel;
import com.gitblit.wicket.panels.RefsPanel;
public abstract class RepositoryPage extends BasePage {
protected final String repositoryName;
protected final String commitId;
protected String description;
public RepositoryPage(PageParameters params, String pageName) {
super(params);
if (!params.containsKey("p")) {
error("Repository not specified!");
redirectToInterceptPage(new RepositoriesPage());
}
repositoryName = params.getString("p", "");
commitId = params.getString("h", "");
add(new PageHeader("pageHeader", repositoryName, "/ " + pageName));
add(new PageLinksPanel("pageLinks", repositoryName, pageName));
setStatelessHint(true);
}
protected Repository getRepository() {
ServletWebRequest servletWebRequest = (ServletWebRequest) getRequest();
HttpServletRequest req = servletWebRequest.getHttpServletRequest();
req.getServerName();
Repository r = GitBlitWebApp.get().getRepository(req, repositoryName);
if (r == null) {
error("Can not load repository " + repositoryName);
redirectToInterceptPage(new RepositoriesPage());
return null;
}
description = JGitUtils.getRepositoryDescription(r);
return r;
}
protected void addRefs(Repository r, RevCommit c) {
add(new RefsPanel("refsPanel", r, c));
}
protected void addFullText(String wicketId, String text, boolean substituteRegex) {
String html = WicketUtils.breakLines(text);
if (substituteRegex) {
Map<String, String> map = new HashMap<String, String>();
// global regex keys
for (String key : StoredSettings.getAllKeys("regex.global")) {
String subKey = key.substring(key.lastIndexOf('.') + 1);
map.put(subKey, StoredSettings.getString(key, ""));
}
// repository-specific regex keys
List<String> keys = StoredSettings.getAllKeys("regex." + repositoryName.toLowerCase());
for (String key : keys) {
String subKey = key.substring(key.lastIndexOf('.') + 1);
map.put(subKey, StoredSettings.getString(key, ""));
}
for (String key : map.keySet()) {
String definition = map.get(key).trim();
String [] chunks = definition.split("!!!");
if (chunks.length == 2) {
html = html.replaceAll(chunks[0], chunks[1]);
} else {
logger.warn(key + " improperly formatted. Use !!! to separate match from replacement: " + definition);
}
}
}
add(new Label(wicketId, html).setEscapeModelStrings(false));
}
protected void addFooter() {
add(new PageFooter("pageFooter", description));
}
protected PageParameters newRepositoryParameter() {
return new PageParameters("p=" + repositoryName);
}
protected PageParameters newCommitParameter() {
return newCommitParameter(commitId);
}
protected PageParameters newCommitParameter(String commitId) {
if (commitId == null || commitId.trim().length() == 0) {
return newRepositoryParameter();
}
return new PageParameters("p=" + repositoryName + ",h=" + commitId);
}
protected PageParameters newPathParameter(String path) {
if (path == null || path.trim().length() == 0) {
return newCommitParameter();
}
return new PageParameters("p=" + repositoryName + ",h=" + commitId + ",f=" + path);
}
}

+ 11
- 0
src/com/gitblit/wicket/SecuredPage.java View File

@@ -0,0 +1,11 @@
package com.gitblit.wicket;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SecuredPage {
}

+ 35
- 0
src/com/gitblit/wicket/WicketUtils.java View File

@@ -0,0 +1,35 @@
package com.gitblit.wicket;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.model.AbstractReadOnlyModel;
public class WicketUtils {
public static void setCssClass(Component container, String value) {
container.add(newAttributeModifier("class", value));
}
public static void setCssStyle(Component container, String value) {
container.add(newAttributeModifier("style", value));
}
public static void setHtmlTitle(Component container, String value) {
container.add(newAttributeModifier("title", value));
}
private static AttributeModifier newAttributeModifier(String attrib, final String value) {
return new AttributeModifier(attrib, true, new AbstractReadOnlyModel<String>() {
private static final long serialVersionUID = 1L;
@Override
public String getObject() {
return value;
}
});
}
public static String breakLines(String string) {
return string.replace("\r", "<br/>").replace("\n", "<br/>");
}
}

+ 45
- 0
src/com/gitblit/wicket/models/PathModel.java View File

@@ -0,0 +1,45 @@
package com.gitblit.wicket.models;
import java.io.Serializable;
import com.gitblit.utils.JGitUtils;
public class PathModel implements Serializable, Comparable<PathModel> {
private static final long serialVersionUID = 1L;
public final String name;
public final String path;
public final long size;
public final int mode;
public final String commitId;
public boolean isParentPath;
public PathModel(String name, String path, long size, int mode, String commitId) {
this.name = name;
this.path = path;
this.size = size;
this.mode = mode;
this.commitId = commitId;
}
public boolean isTree() {
return JGitUtils.isTreeFromMode(mode);
}
public static PathModel getParentPath(String basePath, String commitId) {
String parentPath = null;
if (basePath.lastIndexOf('/') > -1) {
parentPath = basePath.substring(0, basePath.lastIndexOf('/'));
}
PathModel model = new PathModel("..", parentPath, 0, 0040000, commitId);
model.isParentPath = true;
return model;
}
@Override
public int compareTo(PathModel o) {
return path.compareTo(o.path);
}
}

+ 54
- 0
src/com/gitblit/wicket/models/RefModel.java View File

@@ -0,0 +1,54 @@
package com.gitblit.wicket.models;
import java.io.Serializable;
import java.util.Date;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
public class RefModel implements Serializable, Comparable<RefModel> {
private static final long serialVersionUID = 1L;
final String displayName;
transient Ref ref;
final RevCommit commit;
public RefModel(String displayName, Ref ref, RevCommit commit) {
this.displayName = displayName;
this.ref = ref;
this.commit = commit;
}
public Date getDate() {
return JGitUtils.getCommitDate(commit);
}
public String getDisplayName() {
return displayName;
}
public String getName() {
return ref.getName();
}
public ObjectId getCommitId() {
return commit.getId();
}
public String getShortLog() {
return commit.getShortMessage();
}
public ObjectId getObjectId() {
return ref.getObjectId();
}
@Override
public int compareTo(RefModel o) {
return getDate().compareTo(o.getDate());
}
}

+ 20
- 0
src/com/gitblit/wicket/models/RepositoryModel.java View File

@@ -0,0 +1,20 @@
package com.gitblit.wicket.models;
import java.io.Serializable;
import java.util.Date;
public class RepositoryModel implements Serializable {
private static final long serialVersionUID = 1L;
public final String name;
public final String description;
public final String owner;
public final Date lastChange;
public RepositoryModel(String name, String description, String owner, Date lastchange) {
this.name = name;
this.description = description;
this.owner = owner;
this.lastChange = lastchange;
}
}

+ 31
- 0
src/com/gitblit/wicket/pages/BlobPage.html View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<link href="prettify/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="prettify/prettify.js"></script>
</head>
<body onload="prettyPrint()">
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- blob nav links -->
<div class="page_nav2">
<span wicket:id="historyLink"></span> | <span wicket:id="rawLink"></span> | <span wicket:id="headLink"></span>
</div>
<!-- shortlog header -->
<div class="header" wicket:id="shortlog"></div>
<!-- breadcrumbs -->
<div wicket:id="breadcrumbs"></div>
<!-- blob content -->
<pre wicket:id="blobText"></pre>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 94
- 0
src/com/gitblit/wicket/pages/BlobPage.java View File

@@ -0,0 +1,94 @@
package com.gitblit.wicket.pages;
import java.util.HashMap;
import java.util.Map;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.StoredSettings;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
public class BlobPage extends RepositoryPage {
public BlobPage(PageParameters params) {
super(params, "blob");
final String blobPath = params.getString("f", null);
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, commitId);
// blob page links
add(new Label("historyLink", "history"));
add(new Label("rawLink", "raw"));
add(new Label("headLink", "HEAD"));
add(new LinkPanel("shortlog", "title", commit.getShortMessage(), CommitPage.class, newCommitParameter()));
add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, blobPath, commitId));
String extension = null;
if (blobPath.lastIndexOf('.') > -1) {
extension = blobPath.substring(blobPath.lastIndexOf('.') + 1);
}
// Map the extensions to types
Map<String, Integer> map = new HashMap<String, Integer>();
for (String ext : StoredSettings.getStrings("prettyPrintExtensions")) {
map.put(ext.toLowerCase(), 1);
}
for (String ext : StoredSettings.getStrings("imageExtensions")) {
map.put(ext.toLowerCase(), 2);
}
for (String ext : StoredSettings.getStrings("binaryExtensions")) {
map.put(ext.toLowerCase(), 3);
}
if (extension != null) {
int type = 0;
if (map.containsKey(extension)) {
type = map.get(extension);
}
Component c = null;
switch (type) {
case 1:
// PrettyPrint blob text
c = new Label("blobText", JGitUtils.getRawContentAsString(r, commit, blobPath));
WicketUtils.setCssClass(c, "prettyprint");
break;
case 2:
// TODO image blobs
c = new Label("blobText", "Image File");
break;
case 3:
// TODO binary blobs
c = new Label("blobText", "Binary File");
break;
default:
// plain text
c = new Label("blobText", JGitUtils.getRawContentAsString(r, commit, blobPath));
WicketUtils.setCssClass(c, "plainprint");
}
add(c);
} else {
// plain text
Label blobLabel = new Label("blobText", JGitUtils.getRawContentAsString(r, commit, blobPath));
WicketUtils.setCssClass(blobLabel, "plainprint");
add(blobLabel);
}
// close repository
r.close();
// footer
addFooter();
}
}

+ 51
- 0
src/com/gitblit/wicket/pages/CommitPage.html View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- commit nav links -->
<div class="page_nav2">
(parent: <span wicket:id="parentLink"></span>) | <span wicket:id="patchLink"></span>
</div>
<!-- shortlog header -->
<div class="header" wicket:id="shortlog"></div>
<!-- Refs -->
<div wicket:id="refsPanel"></div>
<!-- commit info -->
<div class="title_text">
<table class="object_header">
<tr><td>author</td><td><span wicket:id="commitAuthor">Message goes here</span></td></tr>
<tr><td></td><td><span wicket:id="commitAuthorDate">Message goes here</span></td></tr>
<tr><td>committer</td><td><span wicket:id="commitCommitter">Message goes here</span></td></tr>
<tr><td></td><td><span wicket:id="commitCommitterDate">Message goes here</span></td></tr>
<tr><td>commit</td><td class="sha1"><span wicket:id="commitId">Message goes here</span></td></tr>
<tr><td>tree</td><td class="sha1"><span wicket:id="commitTree">Message goes here</span></td></tr>
<tr><td>parent</td><td class="sha1"><span wicket:id="commitParents">
<div wicket:id="commitParent">Message goes here</div></span></td></tr>
</table>
</div>
<!-- full message -->
<div class="page_body" wicket:id="fullMessage"></div>
<!-- changed paths -->
<div class="list_head"></div>
<table class="diff_tree">
<tr wicket:id="changedPath">
<td class="path"><span wicket:id="pathName"></span></td>
<td></td>
<td><span wicket:id="pathLinks"></span></td>
</tr>
</table>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 106
- 0
src/com/gitblit/wicket/pages/CommitPage.java View File

@@ -0,0 +1,106 @@
package com.gitblit.wicket.pages;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.models.PathModel;
import com.gitblit.wicket.panels.PathLinksPanel;
public class CommitPage extends RepositoryPage {
public CommitPage(PageParameters params) {
super(params, "commit");
final String commitId = params.getString("h", "");
Repository r = getRepository();
RevCommit c = JGitUtils.getCommit(r, commitId);
List<String> parents = new ArrayList<String>();
if (c.getParentCount() > 0) {
for (RevCommit parent : c.getParents()) {
parents.add(parent.name());
}
}
// commit page links
if (parents.size() == 0) {
add(new Label("parentLink", "none"));
} else {
add(new LinkPanel("parentLink", null, parents.get(0).substring(0, 8), CommitPage.class, newCommitParameter(parents.get(0))));
}
add(new Label("patchLink", "patch"));
add(new LinkPanel("shortlog", "title", c.getShortMessage(), ShortLogPage.class, newRepositoryParameter()));
addRefs(r, c);
add(new Label("commitAuthor", JGitUtils.getDisplayName(c.getAuthorIdent())));
String authorDate = GitBlitWebSession.get().formatDateTimeLong(c.getAuthorIdent().getWhen());
add(new Label("commitAuthorDate", authorDate));
add(new Label("commitCommitter", JGitUtils.getDisplayName(c.getCommitterIdent())));
String comitterDate = GitBlitWebSession.get().formatDateTimeLong(c.getCommitterIdent().getWhen());
add(new Label("commitCommitterDate", comitterDate));
add(new Label("commitId", c.getName()));
add(new LinkPanel("commitTree", "list", c.getTree().getName(), TreePage.class, newCommitParameter()));
// Parent Commits
ListDataProvider<String> parentsDp = new ListDataProvider<String>(parents);
DataView<String> parentsView = new DataView<String>("commitParents", parentsDp) {
private static final long serialVersionUID = 1L;
public void populateItem(final Item<String> item) {
String entry = item.getModelObject();
item.add(new LinkPanel("commitParent", "list", entry, CommitPage.class, newCommitParameter(entry)));
}
};
add(parentsView);
addFullText("fullMessage", c.getFullMessage(), true);
// changed paths list
List<PathModel> paths = JGitUtils.getCommitChangedPaths(r, c);
ListDataProvider<PathModel> pathsDp = new ListDataProvider<PathModel>(paths);
DataView<PathModel> pathsView = new DataView<PathModel>("changedPath", pathsDp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<PathModel> item) {
final PathModel entry = item.getModelObject();
if (entry.isTree()) {
item.add(new LinkPanel("pathName", null, entry.path, TreePage.class, newPathParameter(entry.path)));
} else {
item.add(new LinkPanel("pathName", "list", entry.path, BlobPage.class, newPathParameter(entry.path)));
}
item.add(new PathLinksPanel("pathLinks", repositoryName, entry));
String clazz = counter % 2 == 0 ? "dark" : "light";
WicketUtils.setCssClass(item, clazz);
counter++;
}
};
add(pathsView);
// close repository
r.close();
// footer
addFooter();
}
}

+ 26
- 0
src/com/gitblit/wicket/pages/HeadsPage.html View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- shortlog -->
<div class="header" wicket:id="summary"></div>
<table class="heads">
<tbody>
<tr wicket:id="head">
<td><i><span wicket:id="headDate"></span></i></td>
<td><div wicket:id="headName"></div></td>
<td></td>
</tr>
</tbody>
</table>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 63
- 0
src/com/gitblit/wicket/pages/HeadsPage.java View File

@@ -0,0 +1,63 @@
package com.gitblit.wicket.pages;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.Repository;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.Utils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.models.RefModel;
public class HeadsPage extends RepositoryPage {
public HeadsPage(PageParameters params) {
super(params, "heads");
Repository r = getRepository();
List<RefModel> tags = JGitUtils.getHeads(r, -1);
r.close();
// shortlog
add(new LinkPanel("summary", "title", repositoryName, SummaryPage.class, newRepositoryParameter()));
ListDataProvider<RefModel> tagsDp = new ListDataProvider<RefModel>(tags);
DataView<RefModel> tagView = new DataView<RefModel>("head", tagsDp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<RefModel> item) {
final RefModel entry = item.getModelObject();
String date;
if (entry.getDate() != null) {
date = Utils.timeAgo(entry.getDate());
} else {
date = "";
}
Label headDateLabel = new Label("headDate", date);
item.add(headDateLabel);
WicketUtils.setCssClass(headDateLabel, Utils.timeAgoCss(entry.getDate()));
item.add(new LinkPanel("headName", "list name", entry.getDisplayName(), ShortLogPage.class, newCommitParameter(entry.getName())));
String clazz = counter % 2 == 0 ? "dark" : "light";
WicketUtils.setCssClass(item, clazz);
counter++;
}
};
tagView.setItemsPerPage(GitBlitWebApp.PAGING_ITEM_COUNT);
add(tagView);
// footer
addFooter();
}
}

+ 33
- 0
src/com/gitblit/wicket/pages/LogPage.html View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- summary header -->
<div class="header" wicket:id="summary"></div>
<!-- log -->
<div wicket:id="commit">
<div class="header">
<b><span class="age" wicket:id="timeAgo"></span></b>
<span wicket:id="link"></span>
</div>
<div wicket:id="commitRefs"></div>
<div class="title_text">
<div class="log_link">commit | commitdiff | tree</div>
<span wicket:id="commitAuthor"></span>
<span wicket:id="commitDate"></span>
</div>
<div class="log_body" wicket:id="fullMessage"></div>
</div>
<div wicket:id="navigator"></div>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 69
- 0
src/com/gitblit/wicket/pages/LogPage.java View File

@@ -0,0 +1,69 @@
package com.gitblit.wicket.pages;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.Utils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.RefsPanel;
public class LogPage extends RepositoryPage {
public LogPage(PageParameters params) {
super(params, "log");
Repository r = getRepository();
final Map<ObjectId, List<String>> allRefs = JGitUtils.getAllRefs(r);
List<RevCommit> commits = JGitUtils.getRevLog(r, 100);
r.close();
add(new LinkPanel("summary", "title", repositoryName, SummaryPage.class, newRepositoryParameter()));
// log
ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits);
DataView<RevCommit> logView = new DataView<RevCommit>("commit", dp) {
private static final long serialVersionUID = 1L;
public void populateItem(final Item<RevCommit> item) {
final RevCommit entry = item.getModelObject();
final Date date = JGitUtils.getCommitDate(entry);
item.add(new Label("timeAgo", Utils.timeAgo(date)));
item.add(new LinkPanel("link", "title", entry.getShortMessage(), CommitPage.class, newCommitParameter(entry.getName())));
item.add(new RefsPanel("commitRefs", entry, allRefs));
String author = entry.getAuthorIdent().getName();
item.add(createAuthorLabel("commitAuthor", author));
item.add(new Label("commitDate", GitBlitWebSession.get().formatDateTimeLong(date)));
item.add(new Label("fullMessage", WicketUtils.breakLines(entry.getFullMessage())).setEscapeModelStrings(false));
}
};
logView.setItemsPerPage(GitBlitWebApp.PAGING_ITEM_COUNT);
add(logView);
add(new PagingNavigator("navigator", logView));
// footer
addFooter();
}
}

+ 29
- 0
src/com/gitblit/wicket/pages/RepositoriesPage.html View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<div wicket:id="pageHeader"></div>
<div class="index_include" wicket:id="indexInclude"></div>
<table class="project_list">
<tr>
<th wicket:id="orderByRepository">Repository</th>
<th wicket:id="orderByDescription">Description</th>
<th wicket:id="orderByOwner">Owner</th>
<th wicket:id="orderByDate">Last Change</th>
<th></th>
</tr>
<tbody>
<tr wicket:id="repository">
<td><div class="list" wicket:id="repositoryName"></div></td>
<td><div class="list" wicket:id="repositoryDescription"></div></td>
<td><i><span wicket:id="repositoryOwner"></span></i></td>
<td><span wicket:id="repositoryLastChange"></span></td>
<td></td>
</tr>
</tbody>
</table>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 151
- 0
src/com/gitblit/wicket/pages/RepositoriesPage.java View File

@@ -0,0 +1,151 @@
package com.gitblit.wicket.pages;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import com.gitblit.StoredSettings;
import com.gitblit.utils.Utils;
import com.gitblit.wicket.BasePage;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.models.RepositoryModel;
import com.gitblit.wicket.panels.PageFooter;
import com.gitblit.wicket.panels.PageHeader;
public class RepositoriesPage extends BasePage {
public RepositoriesPage() {
add(new PageHeader("pageHeader"));
add(new Label("indexInclude", StoredSettings.getString("indexMessage", "")).setEscapeModelStrings(false));
List<RepositoryModel> rows = GitBlitWebApp.get().getRepositories(getRequest());
DataProvider dp = new DataProvider(rows);
DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("repository", dp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<RepositoryModel> item) {
final RepositoryModel entry = item.getModelObject();
PageParameters pp = new PageParameters("p=" + entry.name);
item.add(new LinkPanel("repositoryName", "list", entry.name, SummaryPage.class, pp));
item.add(new LinkPanel("repositoryDescription", "list", entry.description, SummaryPage.class, pp));
item.add(new Label("repositoryOwner", entry.owner));
String lastChange = Utils.timeAgo(entry.lastChange);
Label lastChangeLabel = new Label("repositoryLastChange", lastChange);
item.add(lastChangeLabel);
WicketUtils.setCssClass(lastChangeLabel, Utils.timeAgoCss(entry.lastChange));
String clazz = counter % 2 == 0 ? "dark" : "light";
WicketUtils.setCssClass(item, clazz);
counter++;
}
};
add(dataView);
add(newSort("orderByRepository", SortBy.repository, dp, dataView));
add(newSort("orderByDescription", SortBy.description, dp, dataView));
add(newSort("orderByOwner", SortBy.owner, dp, dataView));
add(newSort("orderByDate", SortBy.date, dp, dataView));
add(new PageFooter("pageFooter"));
}
protected enum SortBy {
repository, description, owner, date;
}
protected OrderByBorder newSort(String wicketId, SortBy field, SortableDataProvider<?> dp, final DataView<?> dataView) {
return new OrderByBorder(wicketId, field.name(), dp) {
private static final long serialVersionUID = 1L;
@Override
protected void onSortChanged() {
dataView.setCurrentPage(0);
}
};
}
private class DataProvider extends SortableDataProvider<RepositoryModel> {
private static final long serialVersionUID = 1L;
private List<RepositoryModel> list = null;
protected DataProvider(List<RepositoryModel> list) {
this.list = list;
setSort(SortBy.date.name(), false);
}
@Override
public int size() {
if (list == null)
return 0;
return list.size();
}
@Override
public IModel<RepositoryModel> model(RepositoryModel header) {
return new Model<RepositoryModel>(header);
}
@Override
public Iterator<RepositoryModel> iterator(int first, int count) {
SortParam sp = getSort();
String prop = sp.getProperty();
final boolean asc = sp.isAscending();
if (prop == null || prop.equals(SortBy.date.name())) {
Collections.sort(list, new Comparator<RepositoryModel>() {
@Override
public int compare(RepositoryModel o1, RepositoryModel o2) {
if (asc)
return o1.lastChange.compareTo(o2.lastChange);
return o2.lastChange.compareTo(o1.lastChange);
}
});
} else if (prop.equals(SortBy.repository.name())) {
Collections.sort(list, new Comparator<RepositoryModel>() {
@Override
public int compare(RepositoryModel o1, RepositoryModel o2) {
if (asc)
return o1.name.compareTo(o2.name);
return o2.name.compareTo(o1.name);
}
});
} else if (prop.equals(SortBy.owner.name())) {
Collections.sort(list, new Comparator<RepositoryModel>() {
@Override
public int compare(RepositoryModel o1, RepositoryModel o2) {
if (asc)
return o1.owner.compareTo(o2.owner);
return o2.owner.compareTo(o1.owner);
}
});
} else if (prop.equals(SortBy.description.name())) {
Collections.sort(list, new Comparator<RepositoryModel>() {
@Override
public int compare(RepositoryModel o1, RepositoryModel o2) {
if (asc)
return o1.description.compareTo(o2.description);
return o2.description.compareTo(o1.description);
}
});
}
return list.subList(first, first + count).iterator();
}
}
}

+ 31
- 0
src/com/gitblit/wicket/pages/ShortLogPage.html View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- shortlog -->
<div class="header" wicket:id="summary"></div>
<table class="project_list">
<tbody>
<tr wicket:id="commit">
<td><span wicket:id="commitDate"></span></td>
<td><i><span wicket:id="commitAuthor"></span></i></td>
<td><div wicket:id="commitShortMessage"></div></td>
<td><div wicket:id="commitRefs"></div></td>
<td><span wicket:id="commitLinks"></span></td>
</tr>
<tr>
<td colspan="4"><div wicket:id="navigator"></div></td>
</tr>
</tbody>
</table>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 76
- 0
src/com/gitblit/wicket/pages/ShortLogPage.java View File

@@ -0,0 +1,76 @@
package com.gitblit.wicket.pages;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.RefsPanel;
import com.gitblit.wicket.panels.ShortLogLinksPanel;
public class ShortLogPage extends RepositoryPage {
public ShortLogPage(PageParameters params) {
super(params, "shortlog");
Repository r = getRepository();
final Map<ObjectId, List<String>> allRefs = JGitUtils.getAllRefs(r);
List<RevCommit> commits = JGitUtils.getRevLog(r, 100);
r.close();
// shortlog
add(new LinkPanel("summary", "title", repositoryName, SummaryPage.class, newRepositoryParameter()));
ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits);
DataView<RevCommit> shortlogView = new DataView<RevCommit>("commit", dp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<RevCommit> item) {
final RevCommit entry = item.getModelObject();
final Date date = JGitUtils.getCommitDate(entry);
item.add(createShortlogDateLabel("commitDate", date));
String author = entry.getAuthorIdent().getName();
item.add(createAuthorLabel("commitAuthor", author));
String shortMessage = entry.getShortMessage();
String trimmedMessage = trimShortLog(shortMessage);
LinkPanel shortlog = new LinkPanel("commitShortMessage", "list subject", trimmedMessage, CommitPage.class, newCommitParameter(entry.getName()));
if (!shortMessage.equals(trimmedMessage)) {
WicketUtils.setHtmlTitle(shortlog, shortMessage);
}
item.add(shortlog);
item.add(new RefsPanel("commitRefs", entry, allRefs));
item.add(new ShortLogLinksPanel("commitLinks", repositoryName, entry.getName()));
String clazz = counter % 2 == 0 ? "dark" : "light";
WicketUtils.setCssClass(item, clazz);
counter++;
}
};
shortlogView.setItemsPerPage(GitBlitWebApp.PAGING_ITEM_COUNT);
add(shortlogView);
add(new PagingNavigator("navigator", shortlogView));
// footer
addFooter();
}
}

+ 76
- 0
src/com/gitblit/wicket/pages/SummaryPage.html View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- repository info -->
<div class="title">&nbsp;</div>
<table class="projects_list">
<tr id="metadata_desc"><td>description</td><td><span wicket:id="repositoryDescription">Message goes here</span></td></tr>
<tr id="metadata_owner"><td>owner</td><td><span wicket:id="repositoryOwner">Message goes here</span></td></tr>
<tr id="metadata_lchange"><td>last change</td><td><span wicket:id="repositoryLastChange">Message goes here</span></td></tr>
<tr class="metadata_url"><td>URL</td><td><span wicket:id="repositoryCloneUrl">Message goes here</span></td></tr>
</table>
<!-- shortlog -->
<div class="header" wicket:id="shortlog"></div>
<table class="project_list">
<tbody>
<tr wicket:id="commit">
<td><span wicket:id="commitDate"></span></td>
<td><i><span wicket:id="commitAuthor"></span></i></td>
<td><div wicket:id="commitShortMessage"></div></td>
<td><div wicket:id="commitRefs"></div></td>
<td><span wicket:id="commitLinks"></span></td>
</tr>
<tr>
<td colspan="4"><div wicket:id="shortlogMore"></div></td>
</tr>
</tbody>
</table>
<!-- tags -->
<div class="header" wicket:id="tags"></div>
<table class="project_list">
<tbody>
<tr wicket:id="tag">
<td><i><span wicket:id="tagDate"></span></i></td>
<td><div wicket:id="tagName"></div></td>
<td><div wicket:id="tagDescription"></div></td>
<td><span wicket:id="tagLinks"></span></td>
</tr>
<tr>
<td colspan="4"><div wicket:id="tagsMore"></div></td>
</tr>
</tbody>
</table>
<!-- heads -->
<div class="header" wicket:id="heads"></div>
<table class="heads">
<tbody>
<tr wicket:id="head">
<td><i><span wicket:id="headDate"></span></i></td>
<td><div wicket:id="headName"></div></td>
<td><span wicket:id="headLinks"></span></td>
</tr>
</tbody>
</table>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 149
- 0
src/com/gitblit/wicket/pages/SummaryPage.java View File

@@ -0,0 +1,149 @@
package com.gitblit.wicket.pages;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.models.RefModel;
import com.gitblit.wicket.panels.HeadLinksPanel;
import com.gitblit.wicket.panels.RefsPanel;
import com.gitblit.wicket.panels.ShortLogLinksPanel;
import com.gitblit.wicket.panels.TagLinksPanel;
public class SummaryPage extends RepositoryPage {
public SummaryPage(PageParameters params) {
super(params, "summary");
Repository r = getRepository();
final Map<ObjectId, List<String>> allRefs = JGitUtils.getAllRefs(r);
String owner = JGitUtils.getRepositoryOwner(r);
GitBlitWebSession session = GitBlitWebSession.get();
String lastchange = session.formatDateTimeLong(JGitUtils.getLastChange(r));
String cloneurl = GitBlitWebApp.get().getCloneUrl(repositoryName);
// repository description
add(new Label("repositoryDescription", description));
add(new Label("repositoryOwner", owner));
add(new Label("repositoryLastChange", lastchange));
add(new Label("repositoryCloneUrl", cloneurl));
int summaryCount = 16;
// shortlog
add(new LinkPanel("shortlog", "title", "shortlog", ShortLogPage.class, newRepositoryParameter()));
List<RevCommit> commits = JGitUtils.getRevLog(r, summaryCount);
ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits);
DataView<RevCommit> shortlogView = new DataView<RevCommit>("commit", dp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<RevCommit> item) {
RevCommit entry = item.getModelObject();
Date date = JGitUtils.getCommitDate(entry);
item.add(createShortlogDateLabel("commitDate", date));
String author = entry.getAuthorIdent().getName();
item.add(createAuthorLabel("commitAuthor", author));
String shortMessage = entry.getShortMessage();
String trimmedMessage = trimShortLog(shortMessage);
LinkPanel shortlog = new LinkPanel("commitShortMessage", "list subject", trimmedMessage, CommitPage.class, newCommitParameter(entry.getName()));
if (!shortMessage.equals(trimmedMessage)) {
WicketUtils.setHtmlTitle(shortlog, shortMessage);
}
item.add(shortlog);
item.add(new RefsPanel("commitRefs", entry, allRefs));
item.add(new ShortLogLinksPanel("commitLinks", repositoryName, entry.getName()));
setAlternatingBackground(item, counter);
counter++;
}
};
add(shortlogView);
add(new LinkPanel("shortlogMore", "link", "...", ShortLogPage.class, newRepositoryParameter()));
// tags
List<RefModel> tags = JGitUtils.getTags(r, summaryCount);
add(new LinkPanel("tags", "title", "tags", TagsPage.class, newRepositoryParameter()));
ListDataProvider<RefModel> tagsDp = new ListDataProvider<RefModel>(tags);
DataView<RefModel> tagView = new DataView<RefModel>("tag", tagsDp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<RefModel> item) {
final RefModel entry = item.getModelObject();
item.add(createDateLabel("tagDate", entry.getDate()));
item.add(new LinkPanel("tagName", "list name", entry.getDisplayName(), CommitPage.class, newCommitParameter(entry.getCommitId().getName())));
if (entry.getCommitId().equals(entry.getObjectId())) {
// lightweight tag on commit object
item.add(new Label("tagDescription", ""));
} else {
// tag object
item.add(new LinkPanel("tagDescription", "list subject", entry.getShortLog(), TagPage.class, newCommitParameter(entry.getObjectId().getName())));
}
item.add(new TagLinksPanel("tagLinks", repositoryName, entry));
setAlternatingBackground(item, counter);
counter++;
}
};
add(tagView);
add(new LinkPanel("tagsMore", "link", "...", TagsPage.class, newRepositoryParameter()));
// heads
List<RefModel> heads = JGitUtils.getHeads(r, summaryCount);
add(new LinkPanel("heads", "title", "heads", HeadsPage.class, newRepositoryParameter()));
ListDataProvider<RefModel> headsDp = new ListDataProvider<RefModel>(heads);
DataView<RefModel> headsView = new DataView<RefModel>("head", headsDp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<RefModel> item) {
final RefModel entry = item.getModelObject();
item.add(createDateLabel("headDate", entry.getDate()));
item.add(new LinkPanel("headName", "list name", entry.getDisplayName(), ShortLogPage.class, newCommitParameter(entry.getName())));
item.add(new HeadLinksPanel("headLinks", repositoryName, entry));
setAlternatingBackground(item, counter);
counter++;
}
};
add(headsView);
// close the repository
r.close();
// footer
addFooter();
}
}

+ 28
- 0
src/com/gitblit/wicket/pages/TagPage.html View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- summary header -->
<div class="header" wicket:id="commit"></div>
<!-- commit info -->
<div class="title_text">
<table class="object_header">
<tr><td>object</td><td><span wicket:id="tagId">Message goes here</span></td></tr>
<tr><td>author</td><td><span wicket:id="tagAuthor">Message goes here</span></td></tr>
<tr><td></td><td><span wicket:id="tagDate">Message goes here</span></td></tr>
</table>
</div>
<!-- full message -->
<div class="page_body" wicket:id="fullMessage"></div>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 36
- 0
src/com/gitblit/wicket/pages/TagPage.java View File

@@ -0,0 +1,36 @@
package com.gitblit.wicket.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
public class TagPage extends RepositoryPage {
public TagPage(PageParameters params) {
super(params, "tag");
Repository r = getRepository();
RevCommit c = JGitUtils.getCommit(r, commitId);
add(new LinkPanel("commit", "title", c.getName(), CommitPage.class, newCommitParameter()));
add(new LinkPanel("tagId", "list", c.getName(), CommitPage.class, newCommitParameter(c.getName())));
add(new Label("tagAuthor", JGitUtils.getDisplayName(c.getAuthorIdent())));
String authorDate = GitBlitWebSession.get().formatDateTimeLong(c.getAuthorIdent().getWhen());
add(new Label("tagDate", authorDate));
addFullText("fullMessage", c.getFullMessage(), true);
r.close();
// footer
addFooter();
}
}

+ 30
- 0
src/com/gitblit/wicket/pages/TagsPage.html View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- shortlog -->
<div class="header" wicket:id="summary"></div>
<table class="tags">
<tbody>
<tr wicket:id="tag">
<td><i><span wicket:id="tagDate"></span></i></td>
<td><div wicket:id="tagName"></div></td>
<td><div wicket:id="tagDescription"></div></td>
<td><span wicket:id="tagLinks"></span></td>
</tr>
<tr>
<td colspan="4"><div wicket:id="navigator"></div></td>
</tr>
</tbody>
</table>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 64
- 0
src/com/gitblit/wicket/pages/TagsPage.java View File

@@ -0,0 +1,64 @@
package com.gitblit.wicket.pages;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.Repository;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.models.RefModel;
import com.gitblit.wicket.panels.TagLinksPanel;
public class TagsPage extends RepositoryPage {
public TagsPage(PageParameters params) {
super(params, "tags");
Repository r = getRepository();
List<RefModel> tags = JGitUtils.getTags(r, -1);
r.close();
// shortlog
add(new LinkPanel("summary", "title", repositoryName, SummaryPage.class, newRepositoryParameter()));
ListDataProvider<RefModel> tagsDp = new ListDataProvider<RefModel>(tags);
DataView<RefModel> tagView = new DataView<RefModel>("tag", tagsDp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<RefModel> item) {
final RefModel entry = item.getModelObject();
item.add(createDateLabel("tagDate", entry.getDate()));
item.add(new LinkPanel("tagName", "list name", entry.getDisplayName(), CommitPage.class, newCommitParameter(entry.getObjectId().getName())));
if (entry.getCommitId().equals(entry.getObjectId())) {
// lightweight tag on commit object
item.add(new Label("tagDescription", ""));
} else {
// tag object
item.add(new LinkPanel("tagDescription", "list subject", entry.getShortLog(), TagPage.class, newCommitParameter(entry.getObjectId().getName())));
}
item.add(new TagLinksPanel("tagLinks", repositoryName, entry));
setAlternatingBackground(item, counter);
counter++;
}
};
tagView.setItemsPerPage(GitBlitWebApp.PAGING_ITEM_COUNT);
add(tagView);
add(new PagingNavigator("navigator", tagView));
// footer
addFooter();
}
}

+ 35
- 0
src/com/gitblit/wicket/pages/TreePage.html View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- blob nav links -->
<div class="page_nav2">
<span wicket:id="historyLink"></span> | <span wicket:id="headLink"></span>
</div>
<!-- shortlog header -->
<div class="header" wicket:id="shortlog"></div>
<!-- breadcrumbs -->
<div wicket:id="breadcrumbs"></div>
<!-- changed paths -->
<div class="list_head"></div>
<table class="diff_tree">
<tr wicket:id="changedPath">
<td class="mode"><span wicket:id="pathPermissions"></span></td>
<td class="size"><span wicket:id="pathSize"></span></td>
<td><span wicket:id="pathName"></span></td>
<td><span wicket:id="treeLinks"></span></td>
</tr>
</table>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 89
- 0
src/com/gitblit/wicket/pages/TreePage.java View File

@@ -0,0 +1,89 @@
package com.gitblit.wicket.pages;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.ByteFormat;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.models.PathModel;
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
import com.gitblit.wicket.panels.TreeLinksPanel;
public class TreePage extends RepositoryPage {
public TreePage(PageParameters params) {
super(params, "tree");
final String basePath = params.getString("f", null);
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, commitId);
List<PathModel> paths = JGitUtils.getFilesInPath(r, basePath, commit);
// tree page links
add(new Label("historyLink", "history"));
add(new Label("headLink", "HEAD"));
add(new LinkPanel("shortlog", "title", commit.getShortMessage(), CommitPage.class, newCommitParameter()));
// breadcrumbs
if (basePath == null || basePath.trim().length() == 0) {
add(new Label("breadcrumbs", "").setVisible(false));
} else {
add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, basePath, commitId));
paths.add(0, PathModel.getParentPath(basePath, commitId));
}
final ByteFormat byteFormat = new ByteFormat();
// changed paths list
ListDataProvider<PathModel> pathsDp = new ListDataProvider<PathModel>(paths);
DataView<PathModel> pathsView = new DataView<PathModel>("changedPath", pathsDp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<PathModel> item) {
PathModel entry = item.getModelObject();
item.add(new Label("pathPermissions", JGitUtils.getPermissionsFromMode(entry.mode)));
if (entry.isParentPath) {
// parent .. path
item.add(new Label("pathSize", "").setVisible(false));
item.add(new LinkPanel("pathName", null, entry.name, TreePage.class, newPathParameter(entry.path)));
item.add(new Label("treeLinks", "").setVisible(false));
} else {
if (entry.isTree()) {
// folder/tree link
item.add(new Label("pathSize", "-"));
item.add(new LinkPanel("pathName", null, entry.name, TreePage.class, newPathParameter(entry.path)));
} else {
// blob link
item.add(new Label("pathSize", byteFormat.format(entry.size)));
item.add(new LinkPanel("pathName", "list", entry.name, BlobPage.class, newPathParameter(entry.path)));
}
item.add(new TreeLinksPanel("treeLinks", repositoryName, entry));
}
String clazz = counter % 2 == 0 ? "dark" : "light";
WicketUtils.setCssClass(item, clazz);
counter++;
}
};
add(pathsView);
// close repository
r.close();
// footer
addFooter();
}
}

+ 8
- 0
src/com/gitblit/wicket/panels/HeadLinksPanel.html View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<div class="link">
<span wicket:id="shortlog"></span> | <span wicket:id="log"></span> | <span wicket:id="tree"></span>
</div>
</wicket:panel>
</html>

+ 23
- 0
src/com/gitblit/wicket/panels/HeadLinksPanel.java View File

@@ -0,0 +1,23 @@
package com.gitblit.wicket.panels;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.models.RefModel;
import com.gitblit.wicket.pages.LogPage;
import com.gitblit.wicket.pages.ShortLogPage;
public class HeadLinksPanel extends Panel {
private static final long serialVersionUID = 1L;
public HeadLinksPanel(String id, String repositoryName, RefModel tag) {
super(id);
add(new LinkPanel("shortlog", null, "shortlog", ShortLogPage.class, new PageParameters("p=" + repositoryName + ",h=" + tag.getName())));
add(new LinkPanel("log", null, "log", LogPage.class, new PageParameters("p=" + repositoryName + ",h=" + tag.getName())));
add(new Label("tree", "tree"));
}
}

+ 10
- 0
src/com/gitblit/wicket/panels/PageFooter.html View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<div class="page_footer">
<div class="cachetime"><span wicket:id="cacheTime"></span></div>
<div class="page_footer_text"><span wicket:id="footerText"></span></div>
<a title="git homepage" href="http://git-scm.com/">Git</a>
</div>
</wicket:panel>
</html>

+ 28
- 0
src/com/gitblit/wicket/panels/PageFooter.java View File

@@ -0,0 +1,28 @@
package com.gitblit.wicket.panels;
import java.util.Date;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import com.gitblit.StoredSettings;
import com.gitblit.wicket.GitBlitWebSession;
public class PageFooter extends Panel {
private static final long serialVersionUID = 1L;
public PageFooter(String id) {
this(id, "");
}
public PageFooter(String id, String description) {
super(id);
add(new Label("cacheTime", "Page Last Updated: " + GitBlitWebSession.get().formatDateTimeLong(new Date())));
add(new Label("footerText", description));
if (StoredSettings.getBoolean("aggressiveGC", false)) {
System.gc();
}
}
}

+ 15
- 0
src/com/gitblit/wicket/panels/PageHeader.html View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<head>
<title wicket:id="title">Message goes here</title>
<link rel="stylesheet" type="text/css" href="gitblit.css"/>
<link rel="stylesheet" type="text/css" href="gitweb.css"/>
<link rel="shortcut icon" href="git-favicon.png" type="image/png" />
</head>
<div class="page_header">
<a title="gitblit homepage" href="http://gitblit.com/"><img src="gitblt-logo.png" width="91" height="31" alt="gitblit" class="logo"/></a><a href="/"><span wicket:id="siteName">name</span></a> / <span wicket:id="repositoryName">name</span> <span wicket:id="pageName">name</span>
</div>
</wicket:panel>
</html>

+ 41
- 0
src/com/gitblit/wicket/panels/PageHeader.java View File

@@ -0,0 +1,41 @@
package com.gitblit.wicket.panels;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
import com.gitblit.Constants;
import com.gitblit.StoredSettings;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.pages.SummaryPage;
public class PageHeader extends Panel {
private static final long serialVersionUID = 1L;
public PageHeader(String id) {
this(id, "", "");
}
public PageHeader(String id, String repositoryName, String page) {
super(id);
if (repositoryName != null && repositoryName.trim().length() > 0) {
add(new Label("title", getServerName() + " - " + repositoryName));
} else {
add(new Label("title", getServerName()));
}
add(new Label("siteName", StoredSettings.getString("siteName", Constants.NAME)));
add(new LinkPanel("repositoryName", null, repositoryName, SummaryPage.class, new PageParameters("p=" + repositoryName)));
add(new Label("pageName", page));
}
protected String getServerName() {
ServletWebRequest servletWebRequest = (ServletWebRequest) getRequest();
HttpServletRequest req = servletWebRequest.getHttpServletRequest();
return req.getServerName();
}
}

+ 9
- 0
src/com/gitblit/wicket/panels/PageLinksPanel.html View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<!-- page nav links -->
<div class="page_nav">
<span wicket:id="summary"></span> | <span wicket:id="shortlog"></span> | <span wicket:id="log"></span> | <span wicket:id="commit"></span> | <span wicket:id="commitdiff"></span> | <span wicket:id="tree"></span>
</div>
</wicket:panel>
</html>

+ 61
- 0
src/com/gitblit/wicket/panels/PageLinksPanel.java View File

@@ -0,0 +1,61 @@
package com.gitblit.wicket.panels;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.pages.CommitPage;
import com.gitblit.wicket.pages.LogPage;
import com.gitblit.wicket.pages.ShortLogPage;
import com.gitblit.wicket.pages.SummaryPage;
import com.gitblit.wicket.pages.TreePage;
public class PageLinksPanel extends Panel {
private static final long serialVersionUID = 1L;
public PageLinksPanel(String id, String repositoryName, String pageName) {
super(id);
// summary
if (pageName.equals("summary")) {
add(new Label("summary", pageName));
} else {
add(new LinkPanel("summary", null, "summary", SummaryPage.class, new PageParameters("p=" + repositoryName)));
}
// shortlog
if (pageName.equals("shortlog")) {
add(new Label("shortlog", pageName));
} else {
add(new LinkPanel("shortlog", null, "shortlog", ShortLogPage.class, new PageParameters("p=" + repositoryName)));
}
// log
if (pageName.equals("log")) {
add(new Label("log", pageName));
} else {
add(new LinkPanel("log", null, "log", LogPage.class, new PageParameters("p=" + repositoryName)));
}
// commit
if (pageName.equals("commit")) {
add(new Label("commit", pageName));
} else {
add(new LinkPanel("commit", null, "commit", CommitPage.class, new PageParameters("p=" + repositoryName + ",h=HEAD")));
}
// commitdiff
if (pageName.equals("commitdiff")) {
add(new Label("commitdiff", pageName));
} else {
add(new Label("commitdiff", "commitdiff"));
}
// tree
if (pageName.equals("tree")) {
add(new Label("tree", pageName));
} else {
add(new LinkPanel("tree", null, "tree", TreePage.class, new PageParameters("p=" + repositoryName + ",h=HEAD")));
}
}
}

+ 11
- 0
src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.html View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<!-- page path links -->
<div class="page_path">
<span wicket:id="path">
<span wicket:id="pathLink"></span> <span wicket:id="pathSeparator"></span>
</span>
</div>
</wicket:panel>
</html>

+ 79
- 0
src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.java View File

@@ -0,0 +1,79 @@
package com.gitblit.wicket.panels;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.pages.TreePage;
public class PathBreadcrumbsPanel extends Panel {
private static final long serialVersionUID = 1L;
private final String ROOT = "--ROOT--";
public PathBreadcrumbsPanel(String id, final String repositoryName, String pathName, final String commitId) {
super(id);
List<BreadCrumb> crumbs = new ArrayList<BreadCrumb>();
crumbs.add(new BreadCrumb("[" + repositoryName + "]", ROOT, false));
String[] paths = pathName.split("/");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
sb.append(path);
crumbs.add(new BreadCrumb(path, sb.toString(), (i == (paths.length - 1))));
sb.append("/");
}
ListDataProvider<BreadCrumb> crumbsDp = new ListDataProvider<BreadCrumb>(crumbs);
DataView<BreadCrumb> pathsView = new DataView<BreadCrumb>("path", crumbsDp) {
private static final long serialVersionUID = 1L;
public void populateItem(final Item<BreadCrumb> item) {
final BreadCrumb entry = item.getModelObject();
String path = entry.getPath();
String parameters = "p=" + repositoryName + ",h=" + commitId;
if (path != null) {
parameters += ",f=" + path;
}
item.add(new LinkPanel("pathLink", null, entry.name, TreePage.class, new PageParameters(parameters)));
item.add(new Label("pathSeparator", entry.isLeaf ? "":"/"));
}
};
add(pathsView);
}
private class BreadCrumb implements Serializable {
private static final long serialVersionUID = 1L;
final String name;
final String path;
final boolean isLeaf;
BreadCrumb(String name, String path, boolean isLeaf) {
this.name = name;
this.path = path;
this.isLeaf = isLeaf;
}
String getPath() {
if (path.equals(ROOT)) {
return null;
}
return path;
}
}
}

+ 8
- 0
src/com/gitblit/wicket/panels/PathLinksPanel.html View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<div class="link">
<span wicket:id="diff"></span> | <span wicket:id="blob"></span> | <span wicket:id="history"></span>
</div>
</wicket:panel>
</html>

+ 22
- 0
src/com/gitblit/wicket/panels/PathLinksPanel.java View File

@@ -0,0 +1,22 @@
package com.gitblit.wicket.panels;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.models.PathModel;
import com.gitblit.wicket.pages.BlobPage;
public class PathLinksPanel extends Panel {
private static final long serialVersionUID = 1L;
public PathLinksPanel(String id, String repositoryName, PathModel path) {
super(id);
add(new Label("diff", "diff"));
add(new LinkPanel("blob", null, "blob", BlobPage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
add(new Label("history", "history"));
}
}

+ 8
- 0
src/com/gitblit/wicket/panels/RefsPanel.html View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<span class="refs" wicket:id="ref">
<span wicket:id="refName">ref</span>
</span>
</wicket:panel>
</html>

+ 66
- 0
src/com/gitblit/wicket/panels/RefsPanel.java View File

@@ -0,0 +1,66 @@
package com.gitblit.wicket.panels;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.WicketUtils;
public class RefsPanel extends Panel {
private static final long serialVersionUID = 1L;
public RefsPanel(String id, Repository r, RevCommit c) {
this(id, c, JGitUtils.getAllRefs(r));
}
public RefsPanel(String id, RevCommit c, Map<ObjectId, List<String>> refs) {
super(id);
List<String> refNames = refs.get(c.getId());
if (refNames == null) {
refNames = new ArrayList<String>();
}
Collections.sort(refNames);
ListDataProvider<String> refsDp = new ListDataProvider<String>(refNames);
DataView<String> refsView = new DataView<String>("ref", refsDp) {
private static final long serialVersionUID = 1L;
public void populateItem(final Item<String> item) {
String entry = item.getModelObject();
Component c = null;
if (entry.startsWith(Constants.R_HEADS)) {
// local head
c = new Label("refName", entry.substring(Constants.R_HEADS.length()));
WicketUtils.setCssClass(c, "head");
} else if (entry.startsWith(Constants.R_REMOTES)) {
// remote head
c = new Label("refName", entry.substring(Constants.R_REMOTES.length()));
WicketUtils.setCssClass(c, "ref");
} else if (entry.startsWith(Constants.R_TAGS)) {
// tag
c = new Label("refName", entry.substring(Constants.R_TAGS.length()));
WicketUtils.setCssClass(c, "tag");
} else {
// other
c = new Label("refName", entry);
}
WicketUtils.setHtmlTitle(c, entry);
item.add(c);
}
};
add(refsView);
}
}

+ 8
- 0
src/com/gitblit/wicket/panels/ShortLogLinksPanel.html View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<div class="link">
<span wicket:id="commit"></span> | <span wicket:id="commitdiff"></span> | <span wicket:id="tree"></span>
</div>
</wicket:panel>
</html>

+ 23
- 0
src/com/gitblit/wicket/panels/ShortLogLinksPanel.java View File

@@ -0,0 +1,23 @@
package com.gitblit.wicket.panels;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.pages.CommitPage;
import com.gitblit.wicket.pages.TreePage;
public class ShortLogLinksPanel extends Panel {
private static final long serialVersionUID = 1L;
public ShortLogLinksPanel(String id, String repositoryName, String commitId) {
super(id);
add(new LinkPanel("commit", null, "commit", CommitPage.class, new PageParameters("p=" + repositoryName + ",h=" + commitId)));
add(new Label("commitdiff", "commitdiff"));
add(new LinkPanel("tree", null, "tree", TreePage.class, new PageParameters("p=" + repositoryName + ",h=" + commitId)));
}
}

+ 8
- 0
src/com/gitblit/wicket/panels/TagLinksPanel.html View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<div class="link">
<span wicket:id="commit"></span> | <span wicket:id="shortlog"></span> | <span wicket:id="log"></span>
</div>
</wicket:panel>
</html>

+ 0
- 0
src/com/gitblit/wicket/panels/TagLinksPanel.java View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save