prepare ui and repository manager for directory structure

This commit is contained in:
Sebastian Sdorra
2011-10-23 15:56:47 +02:00
parent 744b360fdf
commit 9a06f75bb1
9 changed files with 279 additions and 7 deletions

View File

@@ -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
{

View File

@@ -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));
}

View File

@@ -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 ...).
*

View File

@@ -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 --------------------------------------------------------------
/**

View File

@@ -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
*

View File

@@ -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
*

View File

@@ -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){

View File

@@ -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',

View File

@@ -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);
}
}