James Moger
2014-06-09 65d4270b188ae7b6b3ef7a70fca35c4d7e7696af
commit | author | age
a3456e 1 /*
JM 2  * Copyright 2014 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.wicket.panels;
17
18 import java.text.MessageFormat;
19 import java.util.ArrayList;
577998 20 import java.util.Set;
JM 21 import java.util.TreeSet;
a3456e 22
JM 23 import org.apache.wicket.markup.html.form.DropDownChoice;
24 import org.apache.wicket.markup.html.form.TextField;
f9e51c 25 import org.apache.wicket.model.IModel;
JM 26 import org.apache.wicket.model.Model;
a3456e 27
577998 28 import com.gitblit.models.ProjectModel;
a3456e 29 import com.gitblit.models.RepositoryModel;
JM 30 import com.gitblit.models.UserModel;
31 import com.gitblit.utils.StringUtils;
32 import com.gitblit.wicket.GitBlitWebSession;
33
34 /**
577998 35  * A panel for naming a repository, specifying it's project, and entering a description.
a3456e 36  *
JM 37  * @author James Moger
38  *
39  */
40 public class RepositoryNamePanel extends BasePanel {
41
42     private static final long serialVersionUID = 1L;
43
44     private String fullName;
577998 45
f9e51c 46     private final IModel<String> projectPath;
JM 47
48     private DropDownChoice<String> pathChoice;
49
50     private final IModel<String> repoName;
577998 51
JM 52     private TextField<String> nameField;
a3456e 53
JM 54     public RepositoryNamePanel(String wicketId, RepositoryModel repository) {
55         super(wicketId);
56
57         GitBlitWebSession session = GitBlitWebSession.get();
58         UserModel user = session.getUser();
59
577998 60         // build project set for repository destination
f9e51c 61         String defaultPath = null;
JM 62         String defaultName = null;
63         Set<String> pathNames = new TreeSet<String>();
a3456e 64
577998 65         // add the registered/known projects
JM 66         for (ProjectModel project : app().projects().getProjectModels(user, false)) {
67             // TODO issue-351: user.canAdmin(project)
68             if (user.canAdmin()) {
69                 if (project.isRoot) {
f9e51c 70                     pathNames.add("/");
577998 71                 } else {
f9e51c 72                     pathNames.add(project.name + "/");
577998 73                 }
a3456e 74             }
JM 75         }
76
577998 77         // add the user's personal project namespace
JM 78         if (user.canAdmin() || user.canCreate()) {
f9e51c 79             pathNames.add(user.getPersonalPath() + "/");
577998 80         }
a3456e 81
577998 82         if (!StringUtils.isEmpty(repository.name)) {
JM 83             // editing a repository name
84             // set the defaultProject to the current repository project
f9e51c 85             if (StringUtils.isEmpty(repository.projectPath)) {
JM 86                 defaultPath = "/";
65d427 87                 defaultName = repository.name;
577998 88             } else {
f9e51c 89                 defaultPath = repository.projectPath + "/";
65d427 90                 defaultName = repository.name.substring(defaultPath.length());
577998 91             }
f9e51c 92             pathNames.add(defaultPath);
577998 93         }
JM 94
95         // if default project is not already set, set preference based on the user permissions
f9e51c 96         if (defaultPath == null) {
577998 97             if (user.canAdmin()) {
f9e51c 98                 defaultPath = "/";
577998 99             } else if (user.canCreate()) {
f9e51c 100                 defaultPath = user.getPersonalPath() + "/";
577998 101             }
JM 102         }
103
f9e51c 104         projectPath = Model.of(defaultPath);
JM 105         pathChoice = new DropDownChoice<String>("projectPath", projectPath, new ArrayList<String>(pathNames));
106         repoName = Model.of(defaultName);
107         nameField = new TextField<String>("name", repoName);
577998 108
JM 109         // only enable project selection if we actually have multiple choices
f9e51c 110         add(pathChoice.setEnabled(pathNames.size() > 1));
577998 111         add(nameField);
JM 112         add(new TextField<String>("description"));
113     }
114
115     public void setEditable(boolean editable) {
116         // only enable project selection if we actually have multiple choices
f9e51c 117         pathChoice.setEnabled(pathChoice.getChoices().size() > 1 && editable);
577998 118         nameField.setEnabled(editable);
a3456e 119     }
JM 120
121     public boolean updateModel(RepositoryModel repositoryModel) {
f9e51c 122         // confirm a project path was selected
JM 123         if (StringUtils.isEmpty(projectPath.getObject())) {
a3456e 124             error(getString("gb.pleaseSelectProject"));
JM 125             return false;
126         }
127
128         // confirm a repository name was entered
f9e51c 129         if (StringUtils.isEmpty(repoName.getObject())) {
a3456e 130             error(getString("gb.pleaseSetRepositoryName"));
JM 131             return false;
132         }
133
f9e51c 134         String project = projectPath.getObject();
JM 135         String name = repoName.getObject();
a3456e 136
f9e51c 137         fullName = (project + name).trim();
a3456e 138         fullName = fullName.replace('\\', '/');
JM 139         fullName = fullName.replace("//", "/");
140         if (fullName.charAt(0) == '/') {
141             fullName = fullName.substring(1);
142         }
143         if (fullName.endsWith("/")) {
144             fullName = fullName.substring(0, fullName.length() - 1);
145         }
146
147         if (fullName.contains("../")) {
148             error(getString("gb.illegalRelativeSlash"));
149             return false;
150         }
151         if (fullName.contains("/../")) {
152             error(getString("gb.illegalRelativeSlash"));
153             return false;
154         }
155
156         // confirm valid characters in repository name
157         Character c = StringUtils.findInvalidCharacter(fullName);
158         if (c != null) {
159             error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"), c));
160             return false;
161         }
162
163         repositoryModel.name = fullName;
164
165         return true;
166     }
167
168     @Override
169     protected boolean getStatelessHint() {
170         return false;
171     }
f9e51c 172 }