mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 01:15:44 +01:00
prepare ui and repository manager for directory structure
This commit is contained in:
@@ -219,8 +219,18 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
||||
|
||||
if (isConfigured())
|
||||
{
|
||||
directory = new File(config.getRepositoryDirectory(),
|
||||
repository.getName());
|
||||
File repositoryDirectory = config.getRepositoryDirectory();
|
||||
|
||||
directory = new File(repositoryDirectory, repository.getName());
|
||||
|
||||
if (!IOUtil.isChild(repositoryDirectory, directory))
|
||||
{
|
||||
StringBuilder msg = new StringBuilder(directory.getPath());
|
||||
|
||||
msg.append("is not a child of ").append(repositoryDirectory.getPath());
|
||||
|
||||
throw new ConfigurationException(msg.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -434,7 +434,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject
|
||||
/**
|
||||
* Returns true if the {@link Repository} is valid.
|
||||
* <ul>
|
||||
* <li>The name is not empty and contains only A-z, 0-9, _, -</li>
|
||||
* <li>The name is not empty and contains only A-z, 0-9, _, -, /</li>
|
||||
* <li>The type is not empty</li>
|
||||
* <li>The contact is empty or contains a valid email address</li>
|
||||
* </ul>
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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<Type> 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 ...).
|
||||
*
|
||||
|
||||
@@ -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 --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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<Repository> 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
|
||||
*
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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<Repository, RepositoryException> createManager()
|
||||
protected XmlRepositoryManager createManager()
|
||||
{
|
||||
Set<RepositoryHandler> handlerSet = new HashSet<RepositoryHandler>();
|
||||
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<Set<RepositoryListener>> 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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user