From 9a06f75bb13c4e1dd72e5f282993fff34e9c0978 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 23 Oct 2011 15:56:47 +0200 Subject: [PATCH] prepare ui and repository manager for directory structure --- .../AbstractSimpleRepositoryHandler.java | 14 ++- .../java/sonia/scm/repository/Repository.java | 4 +- .../scm/repository/RepositoryManager.java | 37 ++++++ .../src/main/java/sonia/scm/util/IOUtil.java | 23 ++++ .../java/sonia/scm/util/ValidationUtil.java | 17 +++ .../repository/xml/XmlRepositoryManager.java | 110 ++++++++++++++++++ .../resources/js/override/ext.form.vtypes.js | 7 ++ .../sonia.repository.settingsformpanel.js | 2 +- .../repository/XmlRepositoryManagerTest.java | 72 +++++++++++- 9 files changed, 279 insertions(+), 7 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java index 9feabcbc84..083f0e159a 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java @@ -219,8 +219,18 @@ public abstract class AbstractSimpleRepositoryHandler - *
  • The name is not empty and contains only A-z, 0-9, _, -
  • + *
  • The name is not empty and contains only A-z, 0-9, _, -, /
  • *
  • The type is not empty
  • *
  • The contact is empty or contains a valid email address
  • * @@ -445,7 +445,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject @Override public boolean isValid() { - return ValidationUtil.isNameValid(name) && Util.isNotEmpty(type) + return ValidationUtil.isRepositoryNameValid(name) && Util.isNotEmpty(type) && ((Util.isEmpty(contact)) || ValidationUtil.isMailAddressValid(contact)); } diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java index 355e16faf1..1e90c57d2f 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java @@ -43,6 +43,8 @@ import sonia.scm.TypeManager; import java.util.Collection; +import javax.servlet.http.HttpServletRequest; + /** * The central class for managing {@link Repository} objects. * This class is a singleton and is available via injection. @@ -80,6 +82,41 @@ public interface RepositoryManager */ public Collection getConfiguredTypes(); + /** + * Returns the {@link Repository} associated to the request uri. + * + * + * @param request the current http request + * + * @return associated to the request uri + * @since 1.9 + */ + public Repository getFromRequest(HttpServletRequest request); + + /** + * Returns the {@link Repository} associated to the given type and path. + * + * + * @param type type of the repository (hg, git ...) + * @param uri + * + * @return the {@link Repository} associated to the given type and path + * @since 1.9 + */ + public Repository getFromTypeAndUri(String type, String uri); + + /** + * Returns the {@link Repository} associated to the request uri. + * + * + * + * @param uri request uri without context path + * + * @return associated to the request uri + * @since 1.9 + */ + public Repository getFromUri(String uri); + /** * Returns a {@link RepositoryHandler} by the given type (hg, git, svn ...). * diff --git a/scm-core/src/main/java/sonia/scm/util/IOUtil.java b/scm-core/src/main/java/sonia/scm/util/IOUtil.java index e37ce0a70d..03fbb0f823 100644 --- a/scm-core/src/main/java/sonia/scm/util/IOUtil.java +++ b/scm-core/src/main/java/sonia/scm/util/IOUtil.java @@ -664,6 +664,29 @@ public class IOUtil return getScript(baseFile, baseFile.getAbsolutePath()); } + /** + * Method description + * + * + * @param parent + * @param child + * @since 1.9 + * + * @return + * + */ + public static boolean isChild(File parent, File child) + { + try + { + return child.getCanonicalPath().startsWith(parent.getCanonicalPath()); + } + catch (IOException ex) + { + throw new RuntimeException(ex); + } + } + //~--- methods -------------------------------------------------------------- /** diff --git a/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java b/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java index 7ad5ebfebf..8a5f5f7109 100644 --- a/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java +++ b/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java @@ -51,6 +51,9 @@ public class ValidationUtil /** Field description */ private static final String REGEX_NAME = "^[A-z0-9\\.\\-_]+$"; + /** Field description */ + private static final String REGEX_REPOSITORYNAME = "^[A-z0-9\\.\\-_/]+$"; + /** Field description */ private static final String REGEX_USERNAME = "^[A-z0-9\\.\\-_@]+$"; @@ -125,6 +128,20 @@ public class ValidationUtil return result; } + /** + * Method description + * + * + * @param name + * @since 1.9 + * + * @return + */ + public static boolean isRepositoryNameValid(String name) + { + return Util.isNotEmpty(name) && name.matches(REGEX_REPOSITORYNAME); + } + /** * Method description * diff --git a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java index 4193c24453..b535716719 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java @@ -67,6 +67,7 @@ import sonia.scm.store.Store; import sonia.scm.store.StoreFactory; import sonia.scm.util.AssertUtil; import sonia.scm.util.CollectionAppender; +import sonia.scm.util.HttpUtil; import sonia.scm.util.IOUtil; import sonia.scm.util.SecurityUtil; import sonia.scm.util.Util; @@ -87,6 +88,8 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import javax.servlet.http.HttpServletRequest; + /** * * @author Sebastian Sdorra @@ -625,6 +628,89 @@ public class XmlRepositoryManager extends AbstractRepositoryManager return viewer; } + /** + * Method description + * + * + * @param request + * + * @return + */ + @Override + public Repository getFromRequest(HttpServletRequest request) + { + AssertUtil.assertIsNotNull(request); + + return getFromUri(HttpUtil.getStrippedURI(request)); + } + + /** + * Method description + * + * + * @param type + * @param uri + * + * @return + */ + @Override + public Repository getFromTypeAndUri(String type, String uri) + { + AssertUtil.assertIsNotEmpty(type); + AssertUtil.assertIsNotEmpty(uri); + + Repository repository = null; + + if (handlerMap.containsKey(type)) + { + Collection repositories = repositoryDB.values(); + + for (Repository r : repositories) + { + if (type.equals(r.getType()) && isNameMatching(r, uri)) + { + if (isReader(r)) + { + repository = r.clone(); + } + + break; + } + } + } + + return repository; + } + + /** + * Method description + * + * + * @param uri + * + * @return + */ + @Override + public Repository getFromUri(String uri) + { + AssertUtil.assertIsNotEmpty(uri); + + if (uri.startsWith(HttpUtil.SEPARATOR_PATH)) + { + uri = uri.substring(1); + } + + int typeSeperator = uri.indexOf(HttpUtil.SEPARATOR_PATH); + + AssertUtil.assertPositive(typeSeperator); + + String type = uri.substring(0, typeSeperator); + + uri = uri.substring(typeSeperator + 1); + + return getFromTypeAndUri(type, uri); + } + /** * Method description * @@ -814,6 +900,30 @@ public class XmlRepositoryManager extends AbstractRepositoryManager return handler; } + /** + * Method description + * + * + * @param repository + * @param path + * + * @return + */ + private boolean isNameMatching(Repository repository, String path) + { + boolean result = false; + String name = repository.getName(); + + if (path.startsWith(name)) + { + String sub = path.substring(name.length()); + + result = Util.isEmpty(sub) || sub.startsWith(HttpUtil.SEPARATOR_PATH); + } + + return result; + } + /** * Method description * diff --git a/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js b/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js index 1a73cbef5d..f711e65242 100644 --- a/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js +++ b/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js @@ -51,6 +51,13 @@ Ext.apply(Ext.form.VTypes, { nameText: 'The name is invalid.', + // repository name validator + repositoryName: function(val){ + return /^[A-z0-9\.\-_\/]+$/.test(val); + }, + + repositoryNameText: 'The name of the repository is invalid.', + // username validator username: function(val){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js index 9c2cf57f6a..3987f2076c 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js @@ -43,7 +43,7 @@ Sonia.repository.SettingsFormPanel = Ext.extend(Sonia.repository.FormPanel, { readOnly: update, allowBlank: false, helpText: this.nameHelpText, - vtype: 'name' + vtype: 'repositoryName' },{ fieldLabel: this.typeText, name: 'type', diff --git a/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java index a58f3f292a..dd501461c9 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java @@ -37,16 +37,22 @@ package sonia.scm.repository; import com.google.inject.Provider; -import sonia.scm.Manager; +import org.junit.Test; + +import sonia.scm.Type; import sonia.scm.repository.xml.XmlRepositoryManager; import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.StoreFactory; import sonia.scm.util.MockUtil; +import static org.junit.Assert.*; + import static org.mockito.Mockito.*; //~--- JDK imports ------------------------------------------------------------ +import java.io.IOException; + import java.util.HashSet; import java.util.Set; @@ -57,6 +63,36 @@ import java.util.Set; public class XmlRepositoryManagerTest extends RepositoryManagerTestBase { + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void getRepositoryFromRequestUriTest() + throws RepositoryException, IOException + { + RepositoryManager m = createManager(); + + m.init(contextProvider); + createRepository(m, new Repository("1", "hg", "scm")); + createRepository(m, new Repository("2", "hg", "scm-test")); + createRepository(m, new Repository("3", "git", "project1/test-1")); + createRepository(m, new Repository("4", "git", "project1/test-2")); + assertEquals("scm", m.getFromUri("hg/scm").getName()); + assertEquals("scm-test", m.getFromUri("hg/scm-test").getName()); + assertEquals("scm-test", m.getFromUri("/hg/scm-test").getName()); + assertEquals("project1/test-1", + m.getFromUri("/git/project1/test-1").getName()); + assertEquals("project1/test-1", + m.getFromUri("/git/project1/test-1/ka/some/path").getName()); + assertNull(m.getFromUri("/git/project1/test-3/ka/some/path")); + } + + //~--- methods -------------------------------------------------------------- + /** * Method description * @@ -64,13 +100,29 @@ public class XmlRepositoryManagerTest extends RepositoryManagerTestBase * @return */ @Override - protected Manager createManager() + protected XmlRepositoryManager createManager() { Set handlerSet = new HashSet(); StoreFactory factory = new JAXBStoreFactory(); factory.init(contextProvider); handlerSet.add(new DummyRepositoryHandler(factory)); + handlerSet.add(new DummyRepositoryHandler(factory) + { + @Override + public Type getType() + { + return new Type("hg", "Mercurial"); + } + }); + handlerSet.add(new DummyRepositoryHandler(factory) + { + @Override + public Type getType() + { + return new Type("git", "Git"); + } + }); Provider> listenerProvider = mock(Provider.class); @@ -85,4 +137,20 @@ public class XmlRepositoryManagerTest extends RepositoryManagerTestBase factory, handlerSet, listenerProvider, hookProvider); } + + /** + * Method description + * + * + * @param m + * @param repository + * + * @throws IOException + * @throws RepositoryException + */ + private void createRepository(RepositoryManager m, Repository repository) + throws RepositoryException, IOException + { + m.create(repository); + } }