소스 검색

Partially merged url panel with optional support for app clone urls

tags/v1.3.0
James Moger 11 년 전
부모
커밋
8c92559a48

+ 5
- 2
releases.moxie 파일 보기

- Use standard ServletRequestWrapper instead of custom wrapper (issue 224) - Use standard ServletRequestWrapper instead of custom wrapper (issue 224)
changes: changes:
- Improved the repository url display. This display now indicates your repository access permission, per-protocol.
- Improve Gerrit change ref decoration in the refs panel (issue 206) - Improve Gerrit change ref decoration in the refs panel (issue 206)
- Disable Gson's pretty printing which has a huge performance gain - Disable Gson's pretty printing which has a huge performance gain
- Properly set application/json content-type on api calls - Properly set application/json content-type on api calls
- Updated Japanese translation - Updated Japanese translation
additions: additions:
- Added GO http/https connector thread pool size setting
- Added 3rd-party app clone links for SourceTree and SparkleShare
- Added GO http/https connector thread pool size setting
- Added a server setting to force a particular translation/Locale for all sessions - Added a server setting to force a particular translation/Locale for all sessions
- Added smart Git Daemon serving. If enabled, git:// access will be offered for any repository which permits anonymous access. If the repository permits anonymous cloning, anonymous git:// clone will be permitted while anonmymous git:// pushes will be rejected. - Added smart Git Daemon serving. If enabled, git:// access will be offered for any repository which permits anonymous access. If the repository permits anonymous cloning, anonymous git:// clone will be permitted while anonmymous git:// pushes will be rejected.
- Option to automatically tag branch tips on each push with an incremental revision number - Option to automatically tag branch tips on each push with an incremental revision number
- { name: 'git.daemonBindInterface', defaultValue: 'localhost' } - { name: 'git.daemonBindInterface', defaultValue: 'localhost' }
- { name: 'git.daemonPort', defaultValue: 0 } - { name: 'git.daemonPort', defaultValue: 0 }
- { name: 'git.defaultIncrementalPushTagPrefix', defaultValue: 'r' } - { name: 'git.defaultIncrementalPushTagPrefix', defaultValue: 'r' }
- { name: 'web.allowAppCloneLinks', defaultValue: true }
- { name: 'web.forceDefaultLocale', defaultValue: ' ' } - { name: 'web.forceDefaultLocale', defaultValue: ' ' }
- { name: 'server.nioThreadPoolSize', defaultValue: 50 }
- { name: 'server.nioThreadPoolSize', defaultValue: 50 }
} }
# #

+ 12
- 7
src/main/distrib/data/gitblit.properties 파일 보기

# SINCE 0.5.0 # SINCE 0.5.0
web.otherUrls = web.otherUrls =
# Should app-specific clone links be displayed for SourceTree, SparkleShare, etc?
#
# SINCE 1.3.0
web.allowAppCloneLinks = true
# Choose how to present the repositories list. # Choose how to present the repositories list.
# grouped = group nested/subfolder repositories together (no sorting) # grouped = group nested/subfolder repositories together (no sorting)
# flat = flat list of repositories (sorting allowed) # flat = flat list of repositories (sorting allowed)
# RESTART REQUIRED # RESTART REQUIRED
server.useNio = true server.useNio = true
# If using Jetty NIO connectors, specify the maximum number of concurrent
# http/https worker threads to allow.
#
# SINCE 1.3.0
# RESTART REQUIRED
server.nioThreadPoolSize = 50
# If using Jetty NIO connectors, specify the maximum number of concurrent
# http/https worker threads to allow.
#
# SINCE 1.3.0
# RESTART REQUIRED
server.nioThreadPoolSize = 50
# Context path for the GO application. You might want to change the context # Context path for the GO application. You might want to change the context
# path if running Gitblit behind a proxy layer such as mod_proxy. # path if running Gitblit behind a proxy layer such as mod_proxy.
# #

+ 8
- 8
src/main/java/com/gitblit/GitBlitServer.java 파일 보기

// conditionally configure the http connector // conditionally configure the http connector
if (params.port > 0) { if (params.port > 0) {
Connector httpConnector = createConnector(params.useNIO, settings.getInteger(Keys.server.nioThreadPoolSize, 50), params.port);
Connector httpConnector = createConnector(params.useNIO, settings.getInteger(Keys.server.nioThreadPoolSize, 50), params.port);
String bindInterface = settings.getString(Keys.server.httpBindInterface, null); String bindInterface = settings.getString(Keys.server.httpBindInterface, null);
if (!StringUtils.isEmpty(bindInterface)) { if (!StringUtils.isEmpty(bindInterface)) {
logger.warn(MessageFormat.format("Binding connector on port {0,number,0} to {1}", logger.warn(MessageFormat.format("Binding connector on port {0,number,0} to {1}",
if (serverKeyStore.exists()) { if (serverKeyStore.exists()) {
Connector secureConnector = createSSLConnector(params.alias, serverKeyStore, serverTrustStore, params.storePassword, Connector secureConnector = createSSLConnector(params.alias, serverKeyStore, serverTrustStore, params.storePassword,
caRevocationList, params.useNIO, settings.getInteger(Keys.server.nioThreadPoolSize, 50), params.securePort, params.requireClientCertificates);
caRevocationList, params.useNIO, settings.getInteger(Keys.server.nioThreadPoolSize, 50), params.securePort, params.requireClientCertificates);
String bindInterface = settings.getString(Keys.server.httpsBindInterface, null); String bindInterface = settings.getString(Keys.server.httpsBindInterface, null);
if (!StringUtils.isEmpty(bindInterface)) { if (!StringUtils.isEmpty(bindInterface)) {
logger.warn(MessageFormat.format( logger.warn(MessageFormat.format(
* *
* @param useNIO * @param useNIO
* @param port * @param port
* @param maxThreads
* @param maxThreads
* @return an http connector * @return an http connector
*/ */
private Connector createConnector(boolean useNIO, int port, int maxThreads) {
private Connector createConnector(boolean useNIO, int port, int maxThreads) {
Connector connector; Connector connector;
if (useNIO) { if (useNIO) {
logger.info("Setting up NIO SelectChannelConnector on port " + port); logger.info("Setting up NIO SelectChannelConnector on port " + port);
SelectChannelConnector nioconn = new SelectChannelConnector(); SelectChannelConnector nioconn = new SelectChannelConnector();
nioconn.setSoLingerTime(-1); nioconn.setSoLingerTime(-1);
nioconn.setThreadPool(new QueuedThreadPool(maxThreads));
nioconn.setThreadPool(new QueuedThreadPool(maxThreads));
connector = nioconn; connector = nioconn;
} else { } else {
logger.info("Setting up SocketConnector on port " + port); logger.info("Setting up SocketConnector on port " + port);
* @param storePassword * @param storePassword
* @param caRevocationList * @param caRevocationList
* @param useNIO * @param useNIO
* @param nioThreadPoolSize
* @param nioThreadPoolSize
* @param port * @param port
* @param requireClientCertificates * @param requireClientCertificates
* @return an https connector * @return an https connector
*/ */
private Connector createSSLConnector(String certAlias, File keyStore, File clientTrustStore, private Connector createSSLConnector(String certAlias, File keyStore, File clientTrustStore,
String storePassword, File caRevocationList, boolean useNIO, int nioThreadPoolSize, int port,
String storePassword, File caRevocationList, boolean useNIO, int nioThreadPoolSize, int port,
boolean requireClientCertificates) { boolean requireClientCertificates) {
GitblitSslContextFactory factory = new GitblitSslContextFactory(certAlias, GitblitSslContextFactory factory = new GitblitSslContextFactory(certAlias,
keyStore, clientTrustStore, storePassword, caRevocationList); keyStore, clientTrustStore, storePassword, caRevocationList);
} else { } else {
factory.setWantClientAuth(true); factory.setWantClientAuth(true);
} }
ssl.setThreadPool(new QueuedThreadPool(nioThreadPoolSize));
ssl.setThreadPool(new QueuedThreadPool(nioThreadPoolSize));
connector = ssl; connector = ssl;
} else { } else {
logger.info("Setting up NIO SslSocketConnector on port " + port); logger.info("Setting up NIO SslSocketConnector on port " + port);

+ 4
- 1
src/main/java/com/gitblit/wicket/GitBlitWebApp.properties 파일 보기

gb.externalPermissions = {0} access permissions for {1} are externally maintained gb.externalPermissions = {0} access permissions for {1} are externally maintained
gb.viewAccess = You do not have Gitblit read or write access gb.viewAccess = You do not have Gitblit read or write access
gb.yourProtocolPermissionIs = Your {0} access permission for {1} is {2} gb.yourProtocolPermissionIs = Your {0} access permission for {1} is {2}
gb.sparkleshareInvite = SparkleShare invite
gb.cloneWithSparkleShare = clone with SparkleShare\u2122
gb.cloneWithSourceTree = clone with SourceTree\u2122
gb.cloneWithGitHub = clone with GitHub\u2122 for {0}
gb.cloneWithSmartGit = clone with SmartGit\u2122

+ 0
- 27
src/main/java/com/gitblit/wicket/pages/BasePage.java 파일 보기

import com.gitblit.Constants.FederationStrategy; import com.gitblit.Constants.FederationStrategy;
import com.gitblit.GitBlit; import com.gitblit.GitBlit;
import com.gitblit.Keys; import com.gitblit.Keys;
import com.gitblit.SparkleShareInviteServlet;
import com.gitblit.models.ProjectModel; import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel; import com.gitblit.models.RepositoryModel;
import com.gitblit.models.TeamModel; import com.gitblit.models.TeamModel;
} }
} }
protected String getSparkleShareInviteUrl(RepositoryModel repository) {
if (repository.isBare && repository.isSparkleshared()) {
UserModel user = GitBlitWebSession.get().getUser();
if (user == null) {
user = UserModel.ANONYMOUS;
}
String username = null;
if (UserModel.ANONYMOUS != user) {
username = user.username;
}
if (GitBlit.getBoolean(Keys.git.enableGitServlet, true) || (GitBlit.getInteger(Keys.git.daemonPort, 0) > 0)) {
// Gitblit as server
// ensure user can rewind
if (user.canRewindRef(repository)) {
String baseURL = WicketUtils.getGitblitURL(RequestCycle.get().getRequest());
return SparkleShareInviteServlet.asLink(baseURL, repository.name, username);
}
} else {
// Gitblit as viewer, assume RW+ permission
String baseURL = WicketUtils.getGitblitURL(RequestCycle.get().getRequest());
return SparkleShareInviteServlet.asLink(baseURL, repository.name, username);
}
}
return null;
}
protected List<ProjectModel> getProjectModels() { protected List<ProjectModel> getProjectModels() {
final UserModel user = GitBlitWebSession.get().getUser(); final UserModel user = GitBlitWebSession.get().getUser();
List<ProjectModel> projects = GitBlit.self().getProjectModels(user, true); List<ProjectModel> projects = GitBlit.self().getProjectModels(user, true);

+ 5
- 17
src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java 파일 보기

package com.gitblit.wicket.pages; package com.gitblit.wicket.pages;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.PageParameters; import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.basic.Label;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.GitBlit; import com.gitblit.GitBlit;
import com.gitblit.Keys;
import com.gitblit.models.RepositoryModel; import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel; import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException; import com.gitblit.wicket.GitblitRedirectException;
import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.DetailedRepositoryUrlPanel;
import com.gitblit.wicket.panels.RepositoryUrlPanel;
public class EmptyRepositoryPage extends RootPage { public class EmptyRepositoryPage extends RootPage {
setupPage(repositoryName, getString("gb.emptyRepository")); setupPage(repositoryName, getString("gb.emptyRepository"));
List<String> repositoryUrls = new ArrayList<String>();
if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) {
// add the Gitblit repository url
repositoryUrls.add(getRepositoryUrl(repository));
}
UserModel user = GitBlitWebSession.get().getUser(); UserModel user = GitBlitWebSession.get().getUser();
if (user == null) { if (user == null) {
user = UserModel.ANONYMOUS; user = UserModel.ANONYMOUS;
} }
repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName, UserModel.ANONYMOUS.equals(user) ? "" : user.username));
String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.get(0);
AccessPermission accessPermission = user.getRepositoryPermission(repository).permission;
RepositoryUrlPanel urlPanel = new RepositoryUrlPanel("pushurl", false, user, repository, getLocalizer(), this);
String primaryUrl = urlPanel.getPrimaryUrl();
add(new Label("repository", repositoryName)); add(new Label("repository", repositoryName));
add(new DetailedRepositoryUrlPanel("pushurl", getLocalizer(), this, repository.name, primaryUrl, accessPermission));
add(new Label("cloneSyntax", MessageFormat.format("git clone {0}", repositoryUrls.get(0))));
add(urlPanel);
add(new Label("cloneSyntax", MessageFormat.format("git clone {0}", primaryUrl)));
add(new Label("remoteSyntax", MessageFormat.format("git remote add gitblit {0}\ngit push gitblit master", primaryUrl))); add(new Label("remoteSyntax", MessageFormat.format("git remote add gitblit {0}\ngit push gitblit master", primaryUrl)));
} }
} }

+ 1
- 3
src/main/java/com/gitblit/wicket/pages/SummaryPage.html 파일 보기

<tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="branchStats">[branch stats]</span> <span class="link"><a wicket:id="metrics"><wicket:message key="gb.metrics">[metrics]</wicket:message></a></span></td></tr> <tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="branchStats">[branch stats]</span> <span class="link"><a wicket:id="metrics"><wicket:message key="gb.metrics">[metrics]</wicket:message></a></span></td></tr>
<tr><th style="vertical-align:top;padding-top:4px;"><wicket:message key="gb.repositoryUrl">[URL]</wicket:message>&nbsp;<img style="vertical-align: top;padding-left:3px;" wicket:id="accessRestrictionIcon" /></th> <tr><th style="vertical-align:top;padding-top:4px;"><wicket:message key="gb.repositoryUrl">[URL]</wicket:message>&nbsp;<img style="vertical-align: top;padding-left:3px;" wicket:id="accessRestrictionIcon" /></th>
<td style="padding-top:4px;"> <td style="padding-top:4px;">
<div wicket:id="repositoryPrimaryUrl">[repository primary url]</div>
<div wicket:id="repositoryGitDaemonUrl">[repository git daemon url]</div>
<div wicket:id="repositoryUrlPanel">[repository url panel]</div>
<div wicket:id="otherUrls" > <div wicket:id="otherUrls" >
<div wicket:id="otherUrl" style="padding-top:10px"></div> <div wicket:id="otherUrl" style="padding-top:10px"></div>
</div> </div>
<div wicket:id="repositorySparkleShareInviteUrl">[repository sparkleshare invite url]</div>
</td> </td>
</tr> </tr>
</table> </table>

+ 5
- 29
src/main/java/com/gitblit/wicket/pages/SummaryPage.java 파일 보기

import org.wicketstuff.googlecharts.MarkerType; import org.wicketstuff.googlecharts.MarkerType;
import org.wicketstuff.googlecharts.ShapeMarker; import org.wicketstuff.googlecharts.ShapeMarker;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.GitBlit; import com.gitblit.GitBlit;
import com.gitblit.Keys; import com.gitblit.Keys;
import com.gitblit.models.PathModel; import com.gitblit.models.PathModel;
import com.gitblit.models.RepositoryModel; import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel; import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.JGitUtils; import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.MarkdownUtils; import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils; import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.panels.DetailedRepositoryUrlPanel; import com.gitblit.wicket.panels.DetailedRepositoryUrlPanel;
import com.gitblit.wicket.panels.LinkPanel; import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.LogPanel; import com.gitblit.wicket.panels.LogPanel;
import com.gitblit.wicket.panels.SparkleShareInvitePanel;
import com.gitblit.wicket.panels.RepositoryUrlPanel;
import com.gitblit.wicket.panels.TagsPanel; import com.gitblit.wicket.panels.TagsPanel;
public class SummaryPage extends RepositoryPage { public class SummaryPage extends RepositoryPage {
add(new BookmarkablePageLink<Void>("metrics", MetricsPage.class, add(new BookmarkablePageLink<Void>("metrics", MetricsPage.class,
WicketUtils.newRepositoryParameter(repositoryName))); WicketUtils.newRepositoryParameter(repositoryName)));
List<String> repositoryUrls = new ArrayList<String>();
AccessPermission accessPermission = null;
if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) { if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) {
accessPermission = user.getRepositoryPermission(model).permission;
AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction; AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction;
switch (accessRestriction) { switch (accessRestriction) {
case NONE: case NONE:
default: default:
add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));
} }
// add the Gitblit repository url
repositoryUrls.add(getRepositoryUrl(getRepositoryModel()));
} else { } else {
add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));
} }
repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName, UserModel.ANONYMOUS.equals(user) ? "" : user.username));
String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.remove(0);
add(new DetailedRepositoryUrlPanel("repositoryPrimaryUrl", getLocalizer(), this, model.name, primaryUrl, accessPermission));
Component gitDaemonUrlPanel = createGitDaemonUrlPanel("repositoryGitDaemonUrl", user, model);
if (!StringUtils.isEmpty(primaryUrl) && gitDaemonUrlPanel instanceof DetailedRepositoryUrlPanel) {
WicketUtils.setCssStyle(gitDaemonUrlPanel, "padding-top: 10px");
}
add(gitDaemonUrlPanel);
String sparkleshareUrl = getSparkleShareInviteUrl(model);
if (StringUtils.isEmpty(sparkleshareUrl)) {
add(new Label("repositorySparkleShareInviteUrl").setVisible(false));
} else {
Component sparklesharePanel = new SparkleShareInvitePanel("repositorySparkleShareInviteUrl", getLocalizer(), this, sparkleshareUrl, accessPermission);
WicketUtils.setCssStyle(sparklesharePanel, "padding-top: 10px;");
add(sparklesharePanel);
}
ListDataProvider<String> urls = new ListDataProvider<String>(repositoryUrls);
add(new RepositoryUrlPanel("repositoryUrlPanel", false, user, model, getLocalizer(), this));
List<String> otherUrls = GitBlit.self().getOtherCloneUrls(repositoryName, UserModel.ANONYMOUS.equals(user) ? "" : user.username);
ListDataProvider<String> urls = new ListDataProvider<String>(otherUrls);
DataView<String> otherUrlsView = new DataView<String>("otherUrls", urls) { DataView<String> otherUrlsView = new DataView<String>("otherUrls", urls) {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

+ 14
- 0
src/main/java/com/gitblit/wicket/panels/BasePanel.java 파일 보기

import org.apache.wicket.Component; import org.apache.wicket.Component;
import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model; import org.apache.wicket.model.Model;
import org.apache.wicket.protocol.http.request.WebClientInfo;
import com.gitblit.Constants; import com.gitblit.Constants;
import com.gitblit.GitBlit; import com.gitblit.GitBlit;
} }
return timeUtils; return timeUtils;
} }
protected boolean isWindows() {
return isPlatform("windows");
}
protected boolean isMac() {
return isPlatform("macintosh");
}
protected boolean isPlatform(String platform) {
String ua = ((WebClientInfo) GitBlitWebSession.get().getClientInfo()).getUserAgent();
return ua.toLowerCase().contains(platform);
}
protected void setPersonSearchTooltip(Component component, String value, Constants.SearchType searchType) { protected void setPersonSearchTooltip(Component component, String value, Constants.SearchType searchType) {
if (searchType.equals(Constants.SearchType.AUTHOR)) { if (searchType.equals(Constants.SearchType.AUTHOR)) {

+ 1
- 15
src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java 파일 보기

package com.gitblit.wicket.panels; package com.gitblit.wicket.panels;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.wicket.Component; import org.apache.wicket.Component;
import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.html.panel.Fragment;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.GitBlit; import com.gitblit.GitBlit;
import com.gitblit.Keys; import com.gitblit.Keys;
import com.gitblit.utils.StringUtils; import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.pages.BasePage;
import com.gitblit.wicket.pages.DocsPage; import com.gitblit.wicket.pages.DocsPage;
import com.gitblit.wicket.pages.EditRepositoryPage; import com.gitblit.wicket.pages.EditRepositoryPage;
import com.gitblit.wicket.pages.LogPage; import com.gitblit.wicket.pages.LogPage;
super(wicketId); super(wicketId);
final boolean showSwatch = GitBlit.getBoolean(Keys.web.repositoryListSwatches, true); final boolean showSwatch = GitBlit.getBoolean(Keys.web.repositoryListSwatches, true);
final boolean gitServlet = GitBlit.getBoolean(Keys.git.enableGitServlet, true);
final boolean showSize = GitBlit.getBoolean(Keys.web.showRepositorySizes, true); final boolean showSize = GitBlit.getBoolean(Keys.web.showRepositorySizes, true);
// repository swatch // repository swatch
add(new ExternalLink("syndication", SyndicationServlet.asLink("", entry.name, null, 0))); add(new ExternalLink("syndication", SyndicationServlet.asLink("", entry.name, null, 0)));
List<String> repositoryUrls = new ArrayList<String>();
if (gitServlet) {
// add the Gitblit repository url
repositoryUrls.add(BasePage.getRepositoryUrl(entry));
}
repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(entry.name, UserModel.ANONYMOUS.equals(user) ? "" : user.username));
AccessPermission ap = user.getRepositoryPermission(entry).permission;
String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.remove(0);
add(new DetailedRepositoryUrlPanel("repositoryPrimaryUrl",localizer, parent, entry.name, primaryUrl, ap));
add(new RepositoryUrlPanel("repositoryPrimaryUrl", true, user, entry, localizer, parent));
} }
} }

+ 9
- 21
src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html 파일 보기

lang="en"> lang="en">
<wicket:panel> <wicket:panel>
<span wicket:id="repositoryUrl" style="color: blue;">[repository url]</span><span class="hidden-phone hidden-tablet" wicket:id="copyFunction"></span>
<!-- Plain JavaScript manual copy & paste -->
<wicket:fragment wicket:id="jsPanel">
<span style="vertical-align:baseline;">
<img wicket:id="copyIcon" wicket:message="title:gb.copyToClipboard"></img>
</span>
</wicket:fragment>
<!-- flash-based button-press copy & paste -->
<wicket:fragment wicket:id="clippyPanel">
<object wicket:message="title:gb.copyToClipboard" style="vertical-align:middle;"
wicket:id="clippy"
width="14"
height="14"
bgcolor="#ffffff"
quality="high"
wmode="transparent"
scale="noscale"
allowScriptAccess="always"></object>
</wicket:fragment>
<div wicket:id="repositoryPrimaryUrl">[repository primary url]</div>
<div style="padding-top: 2px;">
<span class="link" wicket:id="appCloneLink">
<span wicket:id="icon"></span>
<span wicket:id="link"></span>
<span wicket:id="separator" style="padding: 0px 5px 0px 5px;"></span>
</span>
</div>
<div wicket:id="repositoryGitDaemonUrl">[repository git daemon url]</div>
</wicket:panel> </wicket:panel>
</html> </html>

+ 207
- 18
src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java 파일 보기

*/ */
package com.gitblit.wicket.panels; package com.gitblit.wicket.panels;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.Localizer;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.markup.html.panel.Fragment;
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.apache.wicket.protocol.http.WebRequest;
import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.GitBlit; import com.gitblit.GitBlit;
import com.gitblit.Keys; import com.gitblit.Keys;
import com.gitblit.SparkleShareInviteServlet;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils; import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.WicketUtils;
/**
* Smart repository url panel which can display multiple Gitblit repository urls
* and also supports 3rd party app clone links.
*
* @author James Moger
*
*/
public class RepositoryUrlPanel extends BasePanel { public class RepositoryUrlPanel extends BasePanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String primaryUrl;
public RepositoryUrlPanel(String wicketId, String url) {
public RepositoryUrlPanel(String wicketId, boolean onlyPrimary, UserModel user,
RepositoryModel repository, Localizer localizer, Component owner) {
super(wicketId); super(wicketId);
add(new Label("repositoryUrl", url));
if (GitBlit.getBoolean(Keys.web.allowFlashCopyToClipboard, true)) {
// clippy: flash-based copy & paste
Fragment fragment = new Fragment("copyFunction", "clippyPanel", this);
String baseUrl = WicketUtils.getGitblitURL(getRequest());
ShockWaveComponent clippy = new ShockWaveComponent("clippy", baseUrl + "/clippy.swf");
clippy.setValue("flashVars", "text=" + StringUtils.encodeURL(url));
fragment.add(clippy);
add(fragment);
if (user == null) {
user = UserModel.ANONYMOUS;
}
List<String> repositoryUrls = new ArrayList<String>();
AccessPermission accessPermission = null;
if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) {
accessPermission = user.getRepositoryPermission(repository).permission;
repositoryUrls.add(getRepositoryUrl(repository));
}
repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repository.name, UserModel.ANONYMOUS.equals(user) ? "" : user.username));
primaryUrl = repositoryUrls.size() == 0 ? "" : repositoryUrls.remove(0);
add(new DetailedRepositoryUrlPanel("repositoryPrimaryUrl", localizer, owner, repository.name, primaryUrl, accessPermission));
if (!onlyPrimary) {
Component gitDaemonUrlPanel = createGitDaemonUrlPanel("repositoryGitDaemonUrl", user, repository);
if (!StringUtils.isEmpty(primaryUrl) && gitDaemonUrlPanel instanceof DetailedRepositoryUrlPanel) {
WicketUtils.setCssStyle(gitDaemonUrlPanel, "padding-top: 10px");
}
add(gitDaemonUrlPanel);
} else { } else {
// javascript: manual copy & paste with modal browser prompt dialog
Fragment fragment = new Fragment("copyFunction", "jsPanel", this);
ContextImage img = WicketUtils.newImage("copyIcon", "clippy.png");
img.add(new JavascriptTextPrompt("onclick", "Copy to Clipboard (Ctrl+C, Enter)", url));
fragment.add(img);
add(fragment);
add(new Label("repositoryGitDaemonUrl").setVisible(false));
}
final List<AppCloneLink> cloneLinks = new ArrayList<AppCloneLink>();
if (user.canClone(repository) && GitBlit.getBoolean(Keys.web.allowAppCloneLinks, true)) {
// universal app clone urls
// cloneLinks.add(new AppCloneLink(localizer.getString("gb.cloneWithSmartGit", owner),
// MessageFormat.format("smartgit://cloneRepo/{0}", primaryUrl),
// "Syntevo SmartGit\u2122"));
if (isWindows()) {
// Windows client app clone urls
cloneLinks.add(new AppCloneLink(localizer.getString("gb.cloneWithSourceTree", owner),
MessageFormat.format("sourcetree://cloneRepo/{0}", primaryUrl),
"Atlassian SourceTree\u2122"));
// cloneLinks.add(new AppCloneLink(
// MessageFormat.format(localizer.getString("gb.cloneWithGitHub", owner), "Windows"),
// MessageFormat.format("github-windows://openRepo/{0}", primaryUrl)));
} else if (isMac()) {
// Mac client app clone urls
cloneLinks.add(new AppCloneLink(localizer.getString("gb.cloneWithSourceTree", owner),
MessageFormat.format("sourcetree://cloneRepo/{0}", primaryUrl),
"Atlassian SourceTree\u2122"));
// cloneLinks.add(new AppCloneLink(
// MessageFormat.format(localizer.getString("gb.cloneWithGitHub", owner), "Mac"),
// MessageFormat.format("github-mac://openRepo/{0}", primaryUrl)));
}
// sparkleshare invite url
String sparkleshareUrl = getSparkleShareInviteUrl(user, repository);
if (!StringUtils.isEmpty(sparkleshareUrl)) {
cloneLinks.add(new AppCloneLink(localizer.getString("gb.cloneWithSparkleShare", owner),
sparkleshareUrl, "SparkleShare \u2122", "icon-star"));
}
}
// app clone links
ListDataProvider<AppCloneLink> appLinks = new ListDataProvider<AppCloneLink>(cloneLinks);
DataView<AppCloneLink> appCloneLinks = new DataView<AppCloneLink>("appCloneLink", appLinks) {
private static final long serialVersionUID = 1L;
int count;
public void populateItem(final Item<AppCloneLink> item) {
final AppCloneLink appLink = item.getModelObject();
item.add(new Label("icon", MessageFormat.format("<i class=\"{0}\"></i>", appLink.icon)).setEscapeModelStrings(false));
LinkPanel linkPanel = new LinkPanel("link", null, appLink.name, appLink.url);
if (!StringUtils.isEmpty(appLink.tooltip)) {
WicketUtils.setHtmlTooltip(linkPanel, appLink.tooltip);
}
item.add(linkPanel);
item.add(new Label("separator", "|").setVisible(count < (cloneLinks.size() - 1)));
count++;
}
};
add(appCloneLinks);
}
public String getPrimaryUrl() {
return primaryUrl;
}
protected String getRepositoryUrl(RepositoryModel repository) {
StringBuilder sb = new StringBuilder();
sb.append(WicketUtils.getGitblitURL(RequestCycle.get().getRequest()));
sb.append(Constants.GIT_PATH);
sb.append(repository.name);
// inject username into repository url if authentication is required
if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE)
&& GitBlitWebSession.get().isLoggedIn()) {
String username = GitBlitWebSession.get().getUsername();
sb.insert(sb.indexOf("://") + 3, username + "@");
}
return sb.toString();
}
protected Component createGitDaemonUrlPanel(String wicketId, UserModel user, RepositoryModel repository) {
int gitDaemonPort = GitBlit.getInteger(Keys.git.daemonPort, 0);
if (gitDaemonPort > 0 && user.canClone(repository)) {
String servername = ((WebRequest) getRequest()).getHttpServletRequest().getServerName();
String gitDaemonUrl;
if (gitDaemonPort == 9418) {
// standard port
gitDaemonUrl = MessageFormat.format("git://{0}/{1}", servername, repository.name);
} else {
// non-standard port
gitDaemonUrl = MessageFormat.format("git://{0}:{1,number,0}/{2}", servername, gitDaemonPort, repository.name);
}
AccessPermission gitDaemonPermission = user.getRepositoryPermission(repository).permission;;
if (gitDaemonPermission.atLeast(AccessPermission.CLONE)) {
if (repository.accessRestriction.atLeast(AccessRestrictionType.CLONE)) {
// can not authenticate clone via anonymous git protocol
gitDaemonPermission = AccessPermission.NONE;
} else if (repository.accessRestriction.atLeast(AccessRestrictionType.PUSH)) {
// can not authenticate push via anonymous git protocol
gitDaemonPermission = AccessPermission.CLONE;
} else {
// normal user permission
}
}
if (AccessPermission.NONE.equals(gitDaemonPermission)) {
// repository prohibits all anonymous access
return new Label(wicketId).setVisible(false);
} else {
// repository allows some form of anonymous access
return new DetailedRepositoryUrlPanel(wicketId, getLocalizer(), this, repository.name, gitDaemonUrl, gitDaemonPermission);
}
} else {
// git daemon is not running
return new Label(wicketId).setVisible(false);
}
}
protected String getSparkleShareInviteUrl(UserModel user, RepositoryModel repository) {
if (repository.isBare && repository.isSparkleshared()) {
String username = null;
if (UserModel.ANONYMOUS != user) {
username = user.username;
}
if (GitBlit.getBoolean(Keys.git.enableGitServlet, true) || (GitBlit.getInteger(Keys.git.daemonPort, 0) > 0)) {
// Gitblit as server
// ensure user can rewind
if (user.canRewindRef(repository)) {
String baseURL = WicketUtils.getGitblitURL(RequestCycle.get().getRequest());
return SparkleShareInviteServlet.asLink(baseURL, repository.name, username);
}
} else {
// Gitblit as viewer, assume RW+ permission
String baseURL = WicketUtils.getGitblitURL(RequestCycle.get().getRequest());
return SparkleShareInviteServlet.asLink(baseURL, repository.name, username);
}
}
return null;
}
static class AppCloneLink implements Serializable {
private static final long serialVersionUID = 1L;
final String name;
final String url;
final String tooltip;
final String icon;
public AppCloneLink(String name, String url, String tooltip) {
this(name, url, tooltip, "icon-download");
}
public AppCloneLink(String name, String url, String tooltip, String icon) {
this.name = name;
this.url = url;
this.tooltip = tooltip;
this.icon = icon;
} }
} }
} }

+ 0
- 18
src/main/java/com/gitblit/wicket/panels/SparkleShareInvitePanel.html 파일 보기

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
xml:lang="en"
lang="en">
<wicket:panel>
<span class="repositoryUrlContainer">
<span class="repositoryUrlEndCap">
<img wicket:id="sparkleshareIcon"></img>
</span>
<span class="repositoryUrl">
<a wicket:id="inviteUrl"><wicket:message key="gb.sparkleshareInvite"></wicket:message></a>
</span>
<span class="hidden-phone hidden-tablet repositoryUrlEndCap" wicket:id="accessPermission">[access permission]</span>
</span>
</wicket:panel>
</html>

+ 0
- 52
src/main/java/com/gitblit/wicket/panels/SparkleShareInvitePanel.java 파일 보기

/*
* Copyright 2013 gitblit.com.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gitblit.wicket.panels;
import org.apache.wicket.Component;
import org.apache.wicket.Localizer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.markup.html.link.ExternalLink;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.wicket.WicketUtils;
public class SparkleShareInvitePanel extends BasePanel {
private static final long serialVersionUID = 1L;
public SparkleShareInvitePanel(String wicketId, Localizer localizer, Component parent, String url, AccessPermission ap) {
super(wicketId);
ContextImage star = WicketUtils.newImage("sparkleshareIcon", "star_16x16.png");
add(star);
add(new ExternalLink("inviteUrl", url));
String note = localizer.getString("gb.externalAccess", parent);
String permission = "";
if (ap != null) {
permission = ap.toString();
if (ap.atLeast(AccessPermission.PUSH)) {
note = localizer.getString("gb.readWriteAccess", parent);
} else if (ap.atLeast(AccessPermission.CLONE)) {
note = localizer.getString("gb.readOnlyAccess", parent);
} else {
note = localizer.getString("gb.viewAccess", parent);
}
}
Label label = new Label("accessPermission", permission);
WicketUtils.setHtmlTooltip(label, note);
add(label);
}
}

Loading…
취소
저장