Merge parallel development

This commit is contained in:
René Pfeuffer
2018-07-02 14:36:04 +02:00
17 changed files with 478 additions and 978 deletions

View File

@@ -67,15 +67,7 @@ import sonia.scm.plugin.DefaultPluginManager;
import sonia.scm.plugin.ExtensionProcessor;
import sonia.scm.plugin.PluginLoader;
import sonia.scm.plugin.PluginManager;
import sonia.scm.repository.DefaultRepositoryManager;
import sonia.scm.repository.DefaultRepositoryProvider;
import sonia.scm.repository.HealthCheckContextListener;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryDAO;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.RepositoryManagerProvider;
import sonia.scm.repository.RepositoryProvider;
import sonia.scm.repository.SpacesStrategy;
import sonia.scm.repository.*;
import sonia.scm.repository.api.HookContextFactory;
import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.repository.spi.HookEventFacade;
@@ -283,9 +275,6 @@ public class ScmServletModule extends ServletModule
bind(UserDAO.class, XmlUserDAO.class);
bind(RepositoryDAO.class, XmlRepositoryDAO.class);
Class<? extends SpacesStrategy> mySpaceStrategy = extensionProcessor.byExtensionPoint(SpacesStrategy.class).iterator().next();
bind(SpacesStrategy.class, mySpaceStrategy);
bindDecorated(RepositoryManager.class, DefaultRepositoryManager.class,
RepositoryManagerProvider.class);
bindDecorated(UserManager.class, DefaultUserManager.class,
@@ -297,7 +286,6 @@ public class ScmServletModule extends ServletModule
// bind sslcontext provider
bind(SSLContext.class).toProvider(SSLContextProvider.class);
// bind ahc
Multibinder<ContentTransformer> transformers =
Multibinder.newSetBinder(binder(), ContentTransformer.class);
@@ -362,6 +350,9 @@ public class ScmServletModule extends ServletModule
// bind events
// bind(LastModifiedUpdateListener.class);
Class<? extends NamespaceStrategy> namespaceStrategy = extensionProcessor.byExtensionPoint(NamespaceStrategy.class).iterator().next();
bind(NamespaceStrategy.class, namespaceStrategy);
}
/**

View File

@@ -0,0 +1,11 @@
package sonia.scm.repository;
import sonia.scm.plugin.Extension;
@Extension
public class DefaultNamespaceStrategy implements NamespaceStrategy{
@Override
public String getNamespace() {
return "42";
}
}

View File

@@ -1,19 +1,19 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* <p>
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -24,13 +24,11 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* <p>
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
@@ -79,73 +77,53 @@ import java.util.concurrent.ThreadFactory;
* @author Sebastian Sdorra
*/
@Singleton
public class DefaultRepositoryManager extends AbstractRepositoryManager
{
public class DefaultRepositoryManager extends AbstractRepositoryManager {
/** Field description */
private static final String THREAD_NAME = "Hook-%s";
/** Field description */
private static final Logger logger =
LoggerFactory.getLogger(DefaultRepositoryManager.class);
private final ScmConfiguration configuration;
private final ExecutorService executorService;
private final Map<String, RepositoryHandler> handlerMap;
private final KeyGenerator keyGenerator;
private final RepositoryDAO repositoryDAO;
private final Set<Type> types;
private RepositoryMatcher repositoryMatcher;
private NamespaceStrategy namespaceStrategy;
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
* @param configuration
* @param contextProvider
* @param keyGenerator
* @param repositoryDAO
* @param handlerSet
* @param repositoryMatcher
* @param spaceStrategy
*/
@Inject
public DefaultRepositoryManager(ScmConfiguration configuration,
SCMContextProvider contextProvider, KeyGenerator keyGenerator,
RepositoryDAO repositoryDAO, Set<RepositoryHandler> handlerSet,
RepositoryMatcher repositoryMatcher, SpacesStrategy spaceStrategy)
{
SCMContextProvider contextProvider, KeyGenerator keyGenerator,
RepositoryDAO repositoryDAO, Set<RepositoryHandler> handlerSet,
RepositoryMatcher repositoryMatcher,
NamespaceStrategy namespaceStrategy) {
this.configuration = configuration;
this.keyGenerator = keyGenerator;
this.repositoryDAO = repositoryDAO;
this.repositoryMatcher = repositoryMatcher;
this.spaceStrategy = spaceStrategy;
this.namespaceStrategy = namespaceStrategy;
//J-
ThreadFactory factory = new ThreadFactoryBuilder()
.setNameFormat(THREAD_NAME).build();
this.executorService = new SubjectAwareExecutorService(
Executors.newCachedThreadPool(factory)
);
//J+
handlerMap = new HashMap<>();
types = new HashSet<>();
for (RepositoryHandler handler : handlerSet)
{
for (RepositoryHandler handler : handlerSet) {
addHandler(contextProvider, handler);
}
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @throws IOException
*/
@Override
public void close() throws IOException
{
public void close() throws IOException {
executorService.shutdown();
for (RepositoryHandler handler : handlerMap.values())
{
for (RepositoryHandler handler : handlerMap.values()) {
IOUtil.close(handler);
}
}
@@ -161,26 +139,22 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @throws RepositoryException
*/
public void create(Repository repository, boolean initRepository)
throws RepositoryException, IOException
{
throws RepositoryException, IOException {
logger.info("create repository {} of type {}", repository.getName(),
repository.getType());
repository.setSpace(spaceStrategy.getCurrentSpace());
RepositoryPermissions.create().check();
AssertUtil.assertIsValid(repository);
if (repositoryDAO.contains(repository))
{
if (repositoryDAO.contains(repository)) {
throw RepositoryAlreadyExistsException.create(repository);
}
repository.setId(keyGenerator.createKey());
repository.setCreationDate(System.currentTimeMillis());
repository.setNamespace(namespaceStrategy.getNamespace());
if (initRepository)
{
if (initRepository) {
getHandler(repository).create(repository);
}
@@ -200,8 +174,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
*/
@Override
public void create(Repository repository)
throws RepositoryException, IOException
{
throws RepositoryException, IOException {
create(repository, true);
}
@@ -216,31 +189,25 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
*/
@Override
public void delete(Repository repository)
throws RepositoryException, IOException
{
if (logger.isInfoEnabled())
{
throws RepositoryException, IOException {
if (logger.isInfoEnabled()) {
logger.info("delete repository {} of type {}", repository.getName(),
repository.getType());
}
RepositoryPermissions.delete(repository).check();
if (configuration.isEnableRepositoryArchive() &&!repository.isArchived())
{
if (configuration.isEnableRepositoryArchive() && !repository.isArchived()) {
throw new RepositoryIsNotArchivedException(
"Repository could not deleted, because it is not archived.");
}
if (repositoryDAO.contains(repository))
{
if (repositoryDAO.contains(repository)) {
fireEvent(HandlerEventType.BEFORE_DELETE, repository);
getHandler(repository).delete(repository);
repositoryDAO.delete(repository);
fireEvent(HandlerEventType.DELETE, repository);
}
else
{
} else {
throw new RepositoryNotFoundException(
"repository ".concat(repository.getName()).concat(" not found"));
}
@@ -257,8 +224,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
*/
@Override
public void importRepository(Repository repository)
throws RepositoryException, IOException
{
throws RepositoryException, IOException {
create(repository, false);
}
@@ -269,7 +235,8 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @param context
*/
@Override
public void init(SCMContextProvider context) {}
public void init(SCMContextProvider context) {
}
/**
* Method description
@@ -282,10 +249,8 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
*/
@Override
public void modify(Repository repository)
throws RepositoryException, IOException
{
if (logger.isInfoEnabled())
{
throws RepositoryException, IOException {
if (logger.isInfoEnabled()) {
logger.info("modify repository {} of type {}", repository.getName(),
repository.getType());
}
@@ -293,19 +258,16 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
AssertUtil.assertIsValid(repository);
Repository oldRepository = repositoryDAO.get(repository.getType(),
repository.getName());
repository.getName());
if (oldRepository != null)
{
if (oldRepository != null) {
RepositoryPermissions.modify(oldRepository).check();
fireEvent(HandlerEventType.BEFORE_MODIFY, repository, oldRepository);
repository.setLastModified(System.currentTimeMillis());
getHandler(repository).modify(repository);
repositoryDAO.modify(repository);
fireEvent(HandlerEventType.MODIFY, repository, oldRepository);
}
else
{
} else {
throw new RepositoryNotFoundException(
"repository ".concat(repository.getName()).concat(" not found"));
}
@@ -322,20 +284,16 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
*/
@Override
public void refresh(Repository repository)
throws RepositoryException, IOException
{
throws RepositoryException, IOException {
AssertUtil.assertIsNotNull(repository);
RepositoryPermissions.read(repository).check();
Repository fresh = repositoryDAO.get(repository.getType(),
repository.getName());
repository.getName());
if (fresh != null)
{
if (fresh != null) {
fresh.copyProperties(repository);
}
else
{
} else {
throw new RepositoryNotFoundException(
"repository ".concat(repository.getName()).concat(" not found"));
}
@@ -352,16 +310,14 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Repository get(String id)
{
public Repository get(String id) {
AssertUtil.assertIsNotEmpty(id);
RepositoryPermissions.read(id).check();
Repository repository = repositoryDAO.get(id);
if (repository != null)
{
if (repository != null) {
repository = repository.clone();
}
@@ -378,15 +334,13 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Repository get(String type, String name)
{
public Repository get(String type, String name) {
AssertUtil.assertIsNotEmpty(type);
AssertUtil.assertIsNotEmpty(name);
Repository repository = repositoryDAO.get(type, name);
if (repository != null)
{
if (repository != null) {
RepositoryPermissions.read(repository).check();
repository = repository.clone();
}
@@ -403,25 +357,21 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Collection<Repository> getAll(Comparator<Repository> comparator)
{
public Collection<Repository> getAll(Comparator<Repository> comparator) {
List<Repository> repositories = Lists.newArrayList();
PermissionActionCheck<Repository> check = RepositoryPermissions.read();
for (Repository repository : repositoryDAO.getAll())
{
for (Repository repository : repositoryDAO.getAll()) {
if (handlerMap.containsKey(repository.getType())
&& check.isPermitted(repository))
{
&& check.isPermitted(repository)) {
Repository r = repository.clone();
repositories.add(r);
}
}
if (comparator != null)
{
if (comparator != null) {
Collections.sort(repositories, comparator);
}
@@ -435,8 +385,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Collection<Repository> getAll()
{
public Collection<Repository> getAll() {
return getAll(null);
}
@@ -453,23 +402,19 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
*/
@Override
public Collection<Repository> getAll(Comparator<Repository> comparator,
int start, int limit)
{
int start, int limit) {
final PermissionActionCheck<Repository> check =
RepositoryPermissions.read();
return Util.createSubCollection(repositoryDAO.getAll(), comparator,
new CollectionAppender<Repository>()
{
@Override
public void append(Collection<Repository> collection, Repository item)
{
if (check.isPermitted(item))
{
collection.add(item.clone());
new CollectionAppender<Repository>() {
@Override
public void append(Collection<Repository> collection, Repository item) {
if (check.isPermitted(item)) {
collection.add(item.clone());
}
}
}
}, start, limit);
}, start, limit);
}
/**
@@ -482,8 +427,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Collection<Repository> getAll(int start, int limit)
{
public Collection<Repository> getAll(int start, int limit) {
return getAll(null, start, limit);
}
@@ -494,14 +438,11 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Collection<Type> getConfiguredTypes()
{
public Collection<Type> getConfiguredTypes() {
List<Type> validTypes = Lists.newArrayList();
for (RepositoryHandler handler : handlerMap.values())
{
if (handler.isConfigured())
{
for (RepositoryHandler handler : handlerMap.values()) {
if (handler.isConfigured()) {
validTypes.add(handler.getType());
}
}
@@ -518,8 +459,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Repository getFromRequest(HttpServletRequest request)
{
public Repository getFromRequest(HttpServletRequest request) {
AssertUtil.assertIsNotNull(request);
return getFromUri(HttpUtil.getStrippedURI(request));
@@ -535,15 +475,12 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Repository getFromTypeAndUri(String type, String uri)
{
if (Strings.isNullOrEmpty(type))
{
public Repository getFromTypeAndUri(String type, String uri) {
if (Strings.isNullOrEmpty(type)) {
throw new ArgumentIsInvalidException("argument type is required");
}
if (Strings.isNullOrEmpty(uri))
{
if (Strings.isNullOrEmpty(uri)) {
throw new ArgumentIsInvalidException("argument uri is required");
}
@@ -552,16 +489,13 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
Repository repository = null;
if (handlerMap.containsKey(type))
{
if (handlerMap.containsKey(type)) {
Collection<Repository> repositories = repositoryDAO.getAll();
PermissionActionCheck<Repository> check = RepositoryPermissions.read();
for (Repository r : repositories)
{
if (repositoryMatcher.matches(r, type, uri))
{
for (Repository r : repositories) {
if (repositoryMatcher.matches(r, type, uri)) {
check.check(r);
repository = r.clone();
@@ -570,8 +504,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
}
}
if ((repository == null) && logger.isDebugEnabled())
{
if ((repository == null) && logger.isDebugEnabled()) {
logger.debug("could not find repository with type {} and uri {}", type,
uri);
}
@@ -588,20 +521,17 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Repository getFromUri(String uri)
{
public Repository getFromUri(String uri) {
AssertUtil.assertIsNotEmpty(uri);
if (uri.startsWith(HttpUtil.SEPARATOR_PATH))
{
if (uri.startsWith(HttpUtil.SEPARATOR_PATH)) {
uri = uri.substring(1);
}
int typeSeperator = uri.indexOf(HttpUtil.SEPARATOR_PATH);
Repository repository = null;
if (typeSeperator > 0)
{
if (typeSeperator > 0) {
String type = uri.substring(0, typeSeperator);
uri = uri.substring(typeSeperator + 1);
@@ -620,8 +550,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public RepositoryHandler getHandler(String type)
{
public RepositoryHandler getHandler(String type) {
return handlerMap.get(type);
}
@@ -632,8 +561,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Long getLastModified()
{
public Long getLastModified() {
return repositoryDAO.getLastModified();
}
@@ -644,8 +572,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @return
*/
@Override
public Collection<Type> getTypes()
{
public Collection<Type> getTypes() {
return types;
}
@@ -660,22 +587,19 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @param handler
*/
private void addHandler(SCMContextProvider contextProvider,
RepositoryHandler handler)
{
RepositoryHandler handler) {
AssertUtil.assertIsNotNull(handler);
Type type = handler.getType();
AssertUtil.assertIsNotNull(type);
if (handlerMap.containsKey(type.getName()))
{
if (handlerMap.containsKey(type.getName())) {
throw new ConfigurationException(
type.getName().concat("allready registered"));
}
if (logger.isInfoEnabled())
{
if (logger.isInfoEnabled()) {
logger.info("added RepositoryHandler {} for type {}", handler.getClass(),
type);
}
@@ -699,46 +623,18 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
* @throws RepositoryException
*/
private RepositoryHandler getHandler(Repository repository)
throws RepositoryException
{
throws RepositoryException {
String type = repository.getType();
RepositoryHandler handler = handlerMap.get(type);
if (handler == null)
{
if (handler == null) {
throw new RepositoryHandlerNotFoundException(
"could not find handler for ".concat(type));
}
else if (!handler.isConfigured())
{
} else if (!handler.isConfigured()) {
throw new RepositoryException("handler is not configured");
}
return handler;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final ScmConfiguration configuration;
/** Field description */
private final ExecutorService executorService;
/** Field description */
private final Map<String, RepositoryHandler> handlerMap;
/** Field description */
private final KeyGenerator keyGenerator;
/** Field description */
private final RepositoryDAO repositoryDAO;
/** Field description */
private final Set<Type> types;
/** Field description */
private RepositoryMatcher repositoryMatcher;
private final SpacesStrategy spaceStrategy;
}