From 5779988cf3a1d737322b2b6a1d568da8713509e7 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Tue, 03 Jun 2014 10:34:51 -0400
Subject: [PATCH] Use RepositoryNamePanel in EditRepositoryPage, rename AccessPolicyPanel

---
 src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.html    |    5 -
 src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.java   |   70 +++++++-------
 src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.html |    7 +
 src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.html   |    4 
 src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java |   89 ++++++++++++-----
 src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java    |    9 -
 src/main/java/com/gitblit/wicket/GitBlitWebApp.properties        |   22 ++--
 src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html   |    7 +
 src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java   |   63 +----------
 9 files changed, 134 insertions(+), 142 deletions(-)

diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
index d90158d..d2d1454 100644
--- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
+++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
@@ -686,16 +686,18 @@
 gb.plugins = plugins
 gb.extensions = extensions
 gb.pleaseSelectProject = Please select the project!
-gb.anonymousPush = Anonymous Pushes
-gb.anonymousPushDescription = Anyone can see, clone, and push to this repository.
-gb.pushRestrictedAuthenticated = Restrict Pushes (Authenticated)
-gb.pushRestrictedAuthenticatedDescription = Anyone can see and clone this repository. All authenticated users can push.
-gb.pushRestrictedNamed = Restrict Pushes (Named)
-gb.pushRestrictedNamedDescription = Anyone can see and clone this repository. You choose who can push.
-gb.cloneRestricted = Restrict Clones & Pushes
-gb.cloneRestrictedDescription = Anyone can see this repository. You choose who can clone and push.
-gb.private = Private
-gb.privateRepoDescription = You choose who can see, clone, and push to this repository.
+gb.accessPolicy = Access Policy
+gb.accessPolicyDescription = Choose an access policy to control visibility, cloning, and pushing to this repository.
+gb.anonymousPolicy = Anonymous View, Clone, & Push
+gb.anonymousPolicyDescription = Anyone can see, clone, and push to this repository.
+gb.authenticatedPushPolicy = Restrict Push (Authenticated)
+gb.authenticatedPushPolicyDescription = Anyone can see and clone this repository. All authenticated users have RW+ push permission.
+gb.namedPushPolicy = Restrict Push (Named)
+gb.namedPushPolicyDescription = Anyone can see and clone this repository. You choose who can push.
+gb.clonePolicy = Restrict Clone & Push
+gb.clonePolicyDescription = Anyone can see this repository. You choose who can clone and push.
+gb.viewPolicy  = Restrict View, Clone, & Push
+gb.viewPolicyDescription = You choose who can see, clone, and push to this repository.
 gb.initialCommit = Initial Commit
 gb.initialCommitDescription = This will allow you to <code>git clone</code> this repository immediately. Skip this step if you have already run <code>git init</code> locally.
 gb.initWithReadme = Include a README
diff --git a/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.html b/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.html
index b7a1976..ccb60a5 100644
--- a/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.html
@@ -24,10 +24,10 @@
 
 		<!-- general tab -->
 		<div class="tab-pane active" id="general">
+		<div wicket:id="namePanel"></div>
+		
 		<table class="plain">
 			<tbody class="settings">
-				<tr><th><wicket:message key="gb.name"></wicket:message></th><td class="edit"><input class="span4" type="text" wicket:id="name" id="name" size="40" tabindex="1" /> &nbsp;<span class="help-inline"><wicket:message key="gb.nameDescription"></wicket:message></span></td></tr>
-				<tr><th><wicket:message key="gb.description"></wicket:message></th><td class="edit"><input class="span4" type="text" wicket:id="description" size="40" tabindex="2" /></td></tr>
 				<tr><th colspan="2"><hr/></th></tr>
 				<tr><th><wicket:message key="gb.origin"></wicket:message></th><td class="edit"><input class="span5" type="text" wicket:id="origin" size="80" tabindex="3" /></td></tr>
 				<tr><th><wicket:message key="gb.headRef"></wicket:message></th><td class="edit"><select class="span3" wicket:id="HEAD" tabindex="4" /> &nbsp;<span class="help-inline"><wicket:message key="gb.headRefDescription"></wicket:message></span></td></tr>
diff --git a/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java
index c18cd51..4759fd0 100644
--- a/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java
@@ -72,10 +72,13 @@
 import com.gitblit.wicket.panels.BasePanel.JavascriptEventConfirmation;
 import com.gitblit.wicket.panels.BulletListPanel;
 import com.gitblit.wicket.panels.RegistrantPermissionsPanel;
+import com.gitblit.wicket.panels.RepositoryNamePanel;
 
 public class EditRepositoryPage extends RootSubPage {
 
 	private final boolean isCreate;
+
+	RepositoryNamePanel namePanel;
 
 	private boolean isAdmin;
 
@@ -263,59 +266,8 @@
 			@Override
 			protected void onSubmit() {
 				try {
-					// confirm a repository name was entered
-					if (repositoryModel.name == null && StringUtils.isEmpty(repositoryModel.name)) {
-						error(getString("gb.pleaseSetRepositoryName"));
+					if (!namePanel.updateModel(repositoryModel)) {
 						return;
-					}
-
-					// ensure name is trimmed
-					repositoryModel.name = repositoryModel.name.trim();
-
-					// automatically convert backslashes to forward slashes
-					repositoryModel.name = repositoryModel.name.replace('\\', '/');
-					// Automatically replace // with /
-					repositoryModel.name = repositoryModel.name.replace("//", "/");
-
-					// prohibit folder paths
-					if (repositoryModel.name.startsWith("/")) {
-						error(getString("gb.illegalLeadingSlash"));
-						return;
-					}
-					if (repositoryModel.name.startsWith("../")) {
-						error(getString("gb.illegalRelativeSlash"));
-						return;
-					}
-					if (repositoryModel.name.contains("/../")) {
-						error(getString("gb.illegalRelativeSlash"));
-						return;
-					}
-					if (repositoryModel.name.endsWith("/")) {
-						repositoryModel.name = repositoryModel.name.substring(0, repositoryModel.name.length() - 1);
-					}
-
-					// confirm valid characters in repository name
-					Character c = StringUtils.findInvalidCharacter(repositoryModel.name);
-					if (c != null) {
-						error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"),
-								c));
-						return;
-					}
-
-					if (user.canCreate() && !user.canAdmin() && allowEditName) {
-						// ensure repository name begins with the user's path
-						if (!repositoryModel.name.startsWith(user.getPersonalPath())) {
-							error(MessageFormat.format(getString("gb.illegalPersonalRepositoryLocation"),
-									user.getPersonalPath()));
-							return;
-						}
-
-						if (repositoryModel.name.equals(user.getPersonalPath())) {
-							// reset path prefix and show error
-							repositoryModel.name = user.getPersonalPath() + "/";
-							error(getString("gb.pleaseSetRepositoryName"));
-							return;
-						}
 					}
 
 					// confirm access restriction selection
@@ -426,6 +378,7 @@
 					}
 				} catch (GitBlitException e) {
 					error(e.getMessage());
+					namePanel.resetModel(repositoryModel);
 					return;
 				}
 				setRedirect(false);
@@ -437,8 +390,10 @@
 		form.add(new SimpleAttributeModifier("autocomplete", "off"));
 
 		// field names reflective match RepositoryModel fields
-		form.add(new TextField<String>("name").setEnabled(allowEditName));
-		form.add(new TextField<String>("description"));
+		namePanel = new RepositoryNamePanel("namePanel", repositoryModel);
+		namePanel.setEditable(allowEditName);
+		form.add(namePanel);
+
 		form.add(ownersPalette);
 		form.add(new CheckBox("allowForks").setEnabled(app().settings().getBoolean(Keys.web.allowForking, true)));
 		DropDownChoice<AccessRestrictionType> accessRestriction = new DropDownChoice<AccessRestrictionType>("accessRestriction",
diff --git a/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.html b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.html
index 05f5601..8e4e74a 100644
--- a/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.html
@@ -12,11 +12,6 @@
 
 		<div wicket:id="namePanel"></div>
 		
-		<div>
-			<b><wicket:message key="gb.description"></wicket:message></b><br/>
-			<input class="span6" type="text" wicket:id="description" />
-		</div>
-		
 		<hr/>
 		
 		<div wicket:id="permissionPanel"></div>
diff --git a/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
index e2e5d4b..0adb1dd 100644
--- a/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
@@ -29,7 +29,6 @@
 import org.apache.wicket.markup.html.form.CheckBox;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
@@ -61,7 +60,7 @@
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.panels.RepositoryNamePanel;
-import com.gitblit.wicket.panels.RepositoryPermissionPanel;
+import com.gitblit.wicket.panels.AccessPolicyPanel;
 
 public class NewRepositoryPage extends RootSubPage {
 
@@ -70,7 +69,7 @@
 	private Model<String> gitignoreModel;
 	private IModel<Boolean> addGitflowModel;
 	private IModel<Boolean> addGitignoreModel;
-	private RepositoryPermissionPanel permissionPanel;
+	private AccessPolicyPanel permissionPanel;
 	private RepositoryNamePanel namePanel;
 
 	public NewRepositoryPage() {
@@ -159,8 +158,6 @@
 		namePanel = new RepositoryNamePanel("namePanel", repositoryModel);
 		form.add(namePanel);
 
-		form.add(new TextField<String>("description"));
-
 		// prepare the default access controls
 		AccessRestrictionType defaultRestriction = AccessRestrictionType.fromName(
 				app().settings().getString(Keys.git.defaultAccessRestriction, AccessRestrictionType.PUSH.name()));
@@ -177,7 +174,7 @@
 		repositoryModel.authorizationControl = defaultControl;
 		repositoryModel.accessRestriction = defaultRestriction;
 
-		permissionPanel = new RepositoryPermissionPanel("permissionPanel", repositoryModel);
+		permissionPanel = new AccessPolicyPanel("permissionPanel", repositoryModel);
 		form.add(permissionPanel);
 
 		//
diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryPermissionPanel.html b/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html
similarity index 76%
rename from src/main/java/com/gitblit/wicket/panels/RepositoryPermissionPanel.html
rename to src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html
index 6a4d5ce..38fa7f6 100644
--- a/src/main/java/com/gitblit/wicket/panels/RepositoryPermissionPanel.html
+++ b/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html
@@ -7,8 +7,11 @@
 <body>
 <wicket:panel>
 
-	<span wicket:id="permissionsGroup">
-			<div wicket:id="permissions">
+	<h4><wicket:message key="gb.accessPolicy"></wicket:message></h4>
+	<p><wicket:message key="gb.accessPolicyDescription"></wicket:message></p>
+		
+	<span wicket:id="policiesGroup">
+			<div wicket:id="policies">
 				<div style="display: inline-block;vertical-align: top;">
 					<input type="radio" wicket:id="radio" />
 					<img wicket:id="image"></img> 
diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryPermissionPanel.java b/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.java
similarity index 62%
rename from src/main/java/com/gitblit/wicket/panels/RepositoryPermissionPanel.java
rename to src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.java
index ed3f1fe..a115e25 100644
--- a/src/main/java/com/gitblit/wicket/panels/RepositoryPermissionPanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.java
@@ -38,15 +38,15 @@
  * @author James Moger
  *
  */
-public class RepositoryPermissionPanel extends BasePanel {
+public class AccessPolicyPanel extends BasePanel {
 
 	private static final long serialVersionUID = 1L;
 
 	private final RepositoryModel repository;
 
-	private RadioGroup<Permission> permissionGroup;
+	private RadioGroup<AccessPolicy> policiesGroup;
 
-	public RepositoryPermissionPanel(String wicketId, RepositoryModel repository) {
+	public AccessPolicyPanel(String wicketId, RepositoryModel repository) {
 		super(wicketId);
 		this.repository = repository;
 	}
@@ -55,44 +55,44 @@
 	protected void onInitialize() {
 		super.onInitialize();
 
-		Permission anonymousPermission = new Permission(getString("gb.anonymousPush"),
-				getString("gb.anonymousPushDescription"),
+		AccessPolicy anonymousPolicy = new AccessPolicy(getString("gb.anonymousPolicy"),
+				getString("gb.anonymousPolicyDescription"),
 				"blank.png",
 				AuthorizationControl.AUTHENTICATED,
 				AccessRestrictionType.NONE);
 
-		Permission authenticatedPermission = new Permission(getString("gb.pushRestrictedAuthenticated"),
-				getString("gb.pushRestrictedAuthenticatedDescription"),
+		AccessPolicy authenticatedPushPolicy = new AccessPolicy(getString("gb.authenticatedPushPolicy"),
+				getString("gb.authenticatedPushPolicyDescription"),
 				"lock_go_16x16.png",
 				AuthorizationControl.AUTHENTICATED,
 				AccessRestrictionType.PUSH);
 
-		Permission publicPermission = new Permission(getString("gb.pushRestrictedNamed"),
-				getString("gb.pushRestrictedNamedDescription"),
+		AccessPolicy namedPushPolicy = new AccessPolicy(getString("gb.namedPushPolicy"),
+				getString("gb.namedPushPolicyDescription"),
 				"lock_go_16x16.png",
 				AuthorizationControl.NAMED,
 				AccessRestrictionType.PUSH);
 
-		Permission protectedPermission = new Permission(getString("gb.cloneRestricted"),
-				getString("gb.cloneRestrictedDescription"),
+		AccessPolicy clonePolicy = new AccessPolicy(getString("gb.clonePolicy"),
+				getString("gb.clonePolicyDescription"),
 				"lock_pull_16x16.png",
 				AuthorizationControl.NAMED,
 				AccessRestrictionType.CLONE);
 
-		Permission privatePermission = new Permission(getString("gb.private"),
-				getString("gb.privateRepoDescription"),
+		AccessPolicy viewPolicy = new AccessPolicy(getString("gb.viewPolicy"),
+				getString("gb.viewPolicyDescription"),
 				"shield_16x16.png",
 				AuthorizationControl.NAMED,
 				AccessRestrictionType.VIEW);
 
-		List<Permission> permissions = new ArrayList<Permission>();
+		List<AccessPolicy> policies = new ArrayList<AccessPolicy>();
 		if (app().settings().getBoolean(Keys.git.allowAnonymousPushes, false)) {
-			permissions.add(anonymousPermission);
+			policies.add(anonymousPolicy);
 		}
-		permissions.add(authenticatedPermission);
-		permissions.add(publicPermission);
-		permissions.add(protectedPermission);
-		permissions.add(privatePermission);
+		policies.add(authenticatedPushPolicy);
+		policies.add(namedPushPolicy);
+		policies.add(clonePolicy);
+		policies.add(viewPolicy);
 
 		AccessRestrictionType defaultRestriction = repository.accessRestriction;
 		if (defaultRestriction == null) {
@@ -106,38 +106,38 @@
 					AuthorizationControl.NAMED.name()));
 		}
 
-		Permission defaultPermission = publicPermission;
-		for (Permission permission : permissions) {
-			if (permission.type == defaultRestriction && permission.control == defaultControl) {
-				defaultPermission = permission;
+		AccessPolicy defaultPolicy = namedPushPolicy;
+		for (AccessPolicy policy : policies) {
+			if (policy.type == defaultRestriction && policy.control == defaultControl) {
+				defaultPolicy = policy;
 			}
 		}
 
-		permissionGroup = new RadioGroup<>("permissionsGroup", new Model<Permission>(defaultPermission));
-		ListView<Permission> permissionsList = new ListView<Permission>("permissions", permissions) {
+		policiesGroup = new RadioGroup<>("policiesGroup", new Model<AccessPolicy>(defaultPolicy));
+		ListView<AccessPolicy> policiesList = new ListView<AccessPolicy>("policies", policies) {
 
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			protected void populateItem(ListItem<Permission> item) {
-				Permission p = item.getModelObject();
-				item.add(new Radio<Permission>("radio", item.getModel()));
+			protected void populateItem(ListItem<AccessPolicy> item) {
+				AccessPolicy p = item.getModelObject();
+				item.add(new Radio<AccessPolicy>("radio", item.getModel()));
 				item.add(WicketUtils.newImage("image",  p.image));
 				item.add(new Label("name", p.name));
 				item.add(new Label("description", p.description));
 			}
 		};
-		permissionGroup.add(permissionsList);
+		policiesGroup.add(policiesList);
 
 		setOutputMarkupId(true);
 
-		add(permissionGroup);
+		add(policiesGroup);
 	}
 
 	public void updateModel(RepositoryModel repository) {
-		Permission permission = permissionGroup.getModelObject();
-		repository.authorizationControl = permission.control;
-		repository.accessRestriction = permission.type;
+		AccessPolicy policy = policiesGroup.getModelObject();
+		repository.authorizationControl = policy.control;
+		repository.accessRestriction = policy.type;
 	}
 
 	@Override
@@ -145,7 +145,7 @@
 		return false;
 	}
 
-	private static class Permission implements Serializable {
+	private static class AccessPolicy implements Serializable {
 
 		private static final long serialVersionUID = 1L;
 
@@ -155,7 +155,7 @@
 		final AuthorizationControl control;
 		final AccessRestrictionType type;
 
-		Permission(String name, String description, String img, AuthorizationControl control, AccessRestrictionType type) {
+		AccessPolicy(String name, String description, String img, AuthorizationControl control, AccessRestrictionType type) {
 			this.name = name;
 			this.description = description;
 			this.image = img;
diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.html b/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.html
index f3a0738..3c65162 100644
--- a/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.html
+++ b/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.html
@@ -11,16 +11,19 @@
 		<tbody class="settings">
 			<tr>
 				<th><wicket:message key="gb.project"></wicket:message></th>
-				<td></td>
 				<th><wicket:message key="gb.name"></wicket:message></th>
 			</tr>
 			<tr>
 				<td><select class="span2" wicket:id="projectPath" /></td>
-				<td style="font-size:24px;color:#ccc;">/</td>
 				<td class="edit"><input class="span3" type="text" wicket:id="name" id="name" /> &nbsp;<span class="help-inline"><wicket:message key="gb.nameDescription"></wicket:message></span></td>
 			</tr>
 		</tbody>
 	</table>
+	
+	<div>
+		<b><wicket:message key="gb.description"></wicket:message></b><br/>
+		<input class="span5" type="text" wicket:id="description" />
+	</div>
 			
 </wicket:panel>
 </body>
diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java b/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java
index 7b20ade..358ff59 100644
--- a/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java
@@ -17,18 +17,20 @@
 
 import java.text.MessageFormat;
 import java.util.ArrayList;
-import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
 
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.TextField;
 
+import com.gitblit.models.ProjectModel;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
 
 /**
- * A radio group panel of the 5 available authorization/access restriction combinations.
+ * A panel for naming a repository, specifying it's project, and entering a description.
  *
  * @author James Moger
  *
@@ -37,44 +39,79 @@
 
 	private static final long serialVersionUID = 1L;
 
-	private final RepositoryModel repository;
-
 	private String fullName;
+
+	private DropDownChoice<String> projectChoice;
+
+	private TextField<String> nameField;
 
 	public RepositoryNamePanel(String wicketId, RepositoryModel repository) {
 		super(wicketId);
-		this.repository = repository;
-	}
-
-	@Override
-	protected void onInitialize() {
-		super.onInitialize();
 
 		GitBlitWebSession session = GitBlitWebSession.get();
 		UserModel user = session.getUser();
 
-		// build project list for repository destination
+		// build project set for repository destination
 		String defaultProject = null;
-		List<String> projects = new ArrayList<String>();
+		Set<String> projectNames = new TreeSet<String>();
 
-		if (user.canAdmin()) {
-			projects.add("/");
-			defaultProject = "/";
-		}
-
-		if (user.canCreate()) {
-			String p =  user.getPersonalPath() + "/";
-			projects.add(p);
-			if (defaultProject == null) {
-				// only prefer personal namespace if default is not already set
-				defaultProject = p;
+		// add the registered/known projects
+		for (ProjectModel project : app().projects().getProjectModels(user, false)) {
+			// TODO issue-351: user.canAdmin(project)
+			if (user.canAdmin()) {
+				if (project.isRoot) {
+					projectNames.add("/");
+				} else {
+					projectNames.add(project.name + "/");
+				}
 			}
 		}
 
-		repository.projectPath = defaultProject;
+		// add the user's personal project namespace
+		if (user.canAdmin() || user.canCreate()) {
+			projectNames.add(user.getPersonalPath() + "/");
+		}
 
-		add(new DropDownChoice<String>("projectPath", projects));
-		add(new TextField<String>("name"));
+		if (!StringUtils.isEmpty(repository.name)) {
+			// editing a repository name
+			// set the defaultProject to the current repository project
+			defaultProject = repository.projectPath;
+			if (StringUtils.isEmpty(defaultProject)) {
+				defaultProject = "/";
+			} else {
+				defaultProject += "/";
+			}
+
+			projectNames.add(defaultProject);
+		}
+
+		// if default project is not already set, set preference based on the user permissions
+		if (defaultProject == null) {
+			if (user.canAdmin()) {
+				defaultProject = "/";
+			} else if (user.canCreate()) {
+				defaultProject = user.getPersonalPath() + "/";
+			}
+		}
+
+		// update the model which is reflectively mapped to the Wicket fields by name
+		repository.projectPath = defaultProject;
+		if (repository.projectPath.length() > 1 && !StringUtils.isEmpty(repository.name)) {
+			repository.name = repository.name.substring(repository.projectPath.length());
+		}
+		projectChoice = new DropDownChoice<String>("projectPath", new ArrayList<String>(projectNames));
+		nameField = new TextField<String>("name");
+
+		// only enable project selection if we actually have multiple choices
+		add(projectChoice.setEnabled(projectNames.size() > 1));
+		add(nameField);
+		add(new TextField<String>("description"));
+	}
+
+	public void setEditable(boolean editable) {
+		// only enable project selection if we actually have multiple choices
+		projectChoice.setEnabled(projectChoice.getChoices().size() > 1 && editable);
+		nameField.setEnabled(editable);
 	}
 
 	public boolean updateModel(RepositoryModel repositoryModel) {

--
Gitblit v1.9.1