From ffabda3f83ec7e95ad1a09a8bcf23b414a4e3c67 Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Fri, 29 Jun 2018 17:10:14 +0200 Subject: [PATCH] Set namespace while creating a repository --- .../annotation/ScmAnnotationProcessor.java | 377 ++++-------------- .../java/sonia/scm/plugin/ExtensionPoint.java | 2 - .../scm/repository/NamespaceStrategy.java | 8 + .../spi/RepositoryServiceResolver.java | 4 +- .../spi/GitRepositoryServiceResolver.java | 2 +- .../spi/HgRepositoryServiceResolver.java | 2 +- .../spi/SvnRepositoryServiceResolver.java | 2 +- .../main/java/sonia/scm/ScmServletModule.java | 11 +- .../repository/DefaultNamespaceStrategy.java | 11 + .../repository/DefaultRepositoryManager.java | 276 +++++-------- .../DefaultRepositoryManagerPerfTest.java | 5 +- .../DefaultRepositoryManagerTest.java | 4 +- 12 files changed, 210 insertions(+), 494 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/NamespaceStrategy.java create mode 100644 scm-webapp/src/main/java/sonia/scm/repository/DefaultNamespaceStrategy.java diff --git a/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java b/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java index b49713d61a..c548f30d45 100644 --- a/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java +++ b/scm-annotation-processor/src/main/java/sonia/scm/annotation/ScmAnnotationProcessor.java @@ -1,9 +1,9 @@ /** * Copyright (c) 2010, Sebastian Sdorra All rights reserved. - * + *

* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + *

* 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. 2. Redistributions in * binary form must reproduce the above copyright notice, this list of @@ -11,7 +11,7 @@ * 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. - * + *

* 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 @@ -22,13 +22,11 @@ * CAUSED AND ON 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. - * + *

* http://bitbucket.org/sdorra/scm-manager - * */ - package sonia.scm.annotation; //~--- non-JDK imports -------------------------------------------------------- @@ -107,84 +105,51 @@ import javax.xml.transform.stream.StreamResult; */ @SupportedAnnotationTypes("*") @MetaInfServices(Processor.class) -@SuppressWarnings({ "Since16", "Since15" }) +@SuppressWarnings({"Since16", "Since15"}) @SupportedSourceVersion(SourceVersion.RELEASE_8) -public final class ScmAnnotationProcessor extends AbstractProcessor -{ +public final class ScmAnnotationProcessor extends AbstractProcessor { - /** Field description */ private static final String DESCRIPTOR_MODULE = "META-INF/scm/module.xml"; - - /** Field description */ private static final String DESCRIPTOR_PLUGIN = "META-INF/scm/plugin.xml"; - - /** Field description */ private static final String EL_MODULE = "module"; - - /** Field description */ private static final String EMPTY = ""; - - /** Field description */ private static final String PROPERTY_VALUE = "yes"; - - /** Field description */ private static final Set SUBSCRIBE_ANNOTATIONS = ImmutableSet.of(Subscribe.class.getName()); - - /** Field description */ private static final Set CLASS_ANNOTATIONS = ImmutableSet.of(new ClassAnnotation("rest-resource", Path.class), new ClassAnnotation("rest-provider", Provider.class)); - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param annotations - * @param roundEnv - * - * @return - */ @Override public boolean process(Set annotations, - RoundEnvironment roundEnv) - { - if (!roundEnv.processingOver()) - { + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { Set descriptorElements = Sets.newHashSet(); Set subscriberAnnotations = Sets.newHashSet(); - for (TypeElement e : annotations) - { + for (TypeElement e : annotations) { PluginAnnotation pa = e.getAnnotation(PluginAnnotation.class); - if (pa != null) - { + if (pa != null) { scanForClassAnnotations(descriptorElements, roundEnv, e, pa.value()); } - if (SUBSCRIBE_ANNOTATIONS.contains(e.getQualifiedName().toString())) - { + if (SUBSCRIBE_ANNOTATIONS.contains(e.getQualifiedName().toString())) { subscriberAnnotations.add(e); } } - for (ClassAnnotation ca : CLASS_ANNOTATIONS) - { + for (ClassAnnotation ca : CLASS_ANNOTATIONS) { TypeElement annotation = findAnnotation(annotations, - ca.annotationClass); + ca.annotationClass); - if (annotation != null) - { + if (annotation != null) { scanForClassAnnotations(descriptorElements, roundEnv, annotation, ca.elementName); } } - for (TypeElement annotation : subscriberAnnotations) - { + for (TypeElement annotation : subscriberAnnotations) { scanForSubscriberAnnotations(descriptorElements, roundEnv, annotation); } @@ -194,46 +159,25 @@ public final class ScmAnnotationProcessor extends AbstractProcessor return false; } - /** - * Method description - * - * - * @param closeable - */ - private void close(Closeable closeable) - { - if (closeable != null) - { - try - { + + private void close(Closeable closeable) { + if (closeable != null) { + try { closeable.close(); - } - catch (IOException ex) - { + } catch (IOException ex) { printException("could not close closeable", ex); } } } - /** - * Method description - * - * - * @param annotations - * @param annotationClass - * - * @return - */ + private TypeElement findAnnotation(Set annotations, - Class annotationClass) - { + Class annotationClass) { TypeElement annotation = null; - for (TypeElement te : annotations) - { - if (te.getQualifiedName().toString().equals(annotationClass.getName())) - { - annotation = te; + for (TypeElement typeElement : annotations) { + if (typeElement.getQualifiedName().toString().equals(annotationClass.getName())) { + annotation = typeElement; break; } @@ -242,24 +186,13 @@ public final class ScmAnnotationProcessor extends AbstractProcessor return annotation; } - /** - * Method description - * - * - * @param filer - * - * @return - * - * @throws IOException - */ - private File findDescriptor(Filer filer) throws IOException - { + + private File findDescriptor(Filer filer) throws IOException { FileObject f = filer.getResource(StandardLocation.CLASS_OUTPUT, EMPTY, - DESCRIPTOR_PLUGIN); + DESCRIPTOR_PLUGIN); File file = new File(f.toUri()); - if (!file.exists()) - { + if (!file.exists()) { f = filer.getResource(StandardLocation.CLASS_OUTPUT, EMPTY, DESCRIPTOR_MODULE); file = new File(f.toUri()); @@ -268,68 +201,40 @@ public final class ScmAnnotationProcessor extends AbstractProcessor return file; } - /** - * Method description - * - * - * @param f - * - * @param file - * - * @return - */ - private Document parseDocument(File file) - { + + private Document parseDocument(File file) { Document doc = null; InputStream input = null; - try - { + try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - if (file.exists()) - { + if (file.exists()) { input = new FileInputStream(file); doc = builder.parse(input); - } - else - { + } else { doc = builder.newDocument(); doc.appendChild(doc.createElement(EL_MODULE)); } - } - catch (ParserConfigurationException | SAXException | IOException - | DOMException ex) - { + } catch (ParserConfigurationException | SAXException | IOException + | DOMException ex) { printException("could not parse document", ex); - } - finally - { + } finally { close(input); } return doc; } - /** - * Method description - * - * - * @param obj - * - * @return - */ - private String prepareArrayElement(Object obj) - { + + private String prepareArrayElement(Object obj) { String v = obj.toString(); - if (v.startsWith("\"")) - { + if (v.startsWith("\"")) { v = v.substring(1); - if (v.endsWith("")) - { + if (v.endsWith("")) { v = v.substring(0, v.length() - 1); } } @@ -337,15 +242,8 @@ public final class ScmAnnotationProcessor extends AbstractProcessor return v; } - /** - * Method description - * - * - * @param msg - * @param throwable - */ - private void printException(String msg, Throwable throwable) - { + + private void printException(String msg, Throwable throwable) { processingEnv.getMessager().printMessage(Kind.ERROR, msg); String stack = Throwables.getStackTraceAsString(throwable); @@ -353,144 +251,98 @@ public final class ScmAnnotationProcessor extends AbstractProcessor processingEnv.getMessager().printMessage(Kind.ERROR, stack); } - /** - * Method description - * - * - * @param descriptorElements - * @param roundEnv - * @param annotation - * @param elementName - * @param elements - * - * @return - */ + private void scanForClassAnnotations( Set descriptorElements, RoundEnvironment roundEnv, - TypeElement annotation, String elementName) - { + TypeElement annotation, String elementName) { + Set classes = Sets.newHashSet(); - for (Element e : roundEnv.getElementsAnnotatedWith(annotation)) - { - if (e.getKind().isClass() || e.getKind().isInterface()) - { + for (Element e : roundEnv.getElementsAnnotatedWith(annotation)) { + + if (isClassOrInterface(e)) { TypeElement type = (TypeElement) e; String desc = processingEnv.getElementUtils().getDocComment(type); - if (desc != null) - { + if (desc != null) { desc = desc.trim(); } - //J- classes.add( new ClassWithAttributes( - type.getQualifiedName().toString(), - desc, - getAttributesFromAnnotation(e, annotation) + type.getQualifiedName().toString(), desc, getAttributesFromAnnotation(e, annotation) ) ); - //J+ } } descriptorElements.add(new ClassSetElement(elementName, classes)); } - /** - * Method description - * - * - * @param descriptorElements - * @param roundEnv - * @param annotation - */ + + private boolean isClassOrInterface(Element e) { + return e.getKind().isClass() || e.getKind().isInterface(); + } + + private void scanForSubscriberAnnotations( Set descriptorElements, RoundEnvironment roundEnv, - TypeElement annotation) - { - for (Element el : roundEnv.getElementsAnnotatedWith(annotation)) - { - if (el.getKind() == ElementKind.METHOD) - { + TypeElement annotation) { + for (Element el : roundEnv.getElementsAnnotatedWith(annotation)) { + if (el.getKind() == ElementKind.METHOD) { ExecutableElement ee = (ExecutableElement) el; List params = ee.getParameters(); - if ((params != null) && (params.size() == 1)) - { + if ((params != null) && (params.size() == 1)) { VariableElement param = params.get(0); Element clazz = el.getEnclosingElement(); String desc = processingEnv.getElementUtils().getDocComment(clazz); - if (desc != null) - { + if (desc != null) { desc = desc.trim(); } - //J- descriptorElements.add( new SubscriberElement( - clazz.toString(), + clazz.toString(), param.asType().toString(), desc ) ); - //J+ } } } } - /** - * Method description - * - * - * @param descriptorElements - */ - private void write(Set descriptorElements) - { + + private void write(Set descriptorElements) { Filer filer = processingEnv.getFiler(); - try - { + try { File file = findDescriptor(filer); Document doc = parseDocument(file); - if (doc != null) - { + if (doc != null) { org.w3c.dom.Element root = doc.getDocumentElement(); - for (DescriptorElement el : descriptorElements) - { + for (DescriptorElement el : descriptorElements) { el.append(doc, root); } writeDocument(doc, file); } - } - catch (IOException ex) - { + } catch (IOException ex) { printException("could not open plugin descriptor", ex); } } - /** - * Method description - * - * - * @param doc - * @param f - * @param file - */ - private void writeDocument(Document doc, File file) - { + + private void writeDocument(Document doc, File file) { Writer writer = null; - try - { + try { file.getParentFile().mkdirs(); writer = new FileWriter(file); @@ -499,42 +351,24 @@ public final class ScmAnnotationProcessor extends AbstractProcessor transformer.setOutputProperty(OutputKeys.INDENT, PROPERTY_VALUE); transformer.transform(new DOMSource(doc), new StreamResult(writer)); - } - catch (IOException | IllegalArgumentException | TransformerException ex) - { + } catch (IOException | IllegalArgumentException | TransformerException ex) { printException("could not write document", ex); - } - finally - { + } finally { close(writer); } } - //~--- get methods ---------------------------------------------------------- - /** - * Method description - * - * - * @param el - * @param annotation - * - * @return - */ private Map getAttributesFromAnnotation(Element el, - TypeElement annotation) - { + TypeElement annotation) { Map attributes = Maps.newHashMap(); - for (AnnotationMirror am : el.getAnnotationMirrors()) - { - String qn = am.getAnnotationType().asElement().toString(); + for (AnnotationMirror annotationMirror : el.getAnnotationMirrors()) { + String qn = annotationMirror.getAnnotationType().asElement().toString(); - if (qn.equals(annotation.toString())) - { + if (qn.equals(annotation.toString())) { for (Entry entry : am.getElementValues().entrySet()) - { + ? extends AnnotationValue> entry : annotationMirror.getElementValues().entrySet()) { attributes.put(entry.getKey().getSimpleName().toString(), getValue(entry.getValue())); } @@ -544,77 +378,42 @@ public final class ScmAnnotationProcessor extends AbstractProcessor return attributes; } - /** - * Method description - * - * - * @param v - * - * @return - */ - private String getValue(AnnotationValue v) - { + + private String getValue(AnnotationValue v) { String value; Object object = v.getValue(); - if (object instanceof Iterable) - { + if (object instanceof Iterable) { Iterator it = ((Iterable) object).iterator(); StringBuilder buffer = new StringBuilder(); - while (it.hasNext()) - { + while (it.hasNext()) { buffer.append(prepareArrayElement(it.next())); - if (it.hasNext()) - { + if (it.hasNext()) { buffer.append(","); } - } value = buffer.toString(); - } - else - { + } else { value = object.toString(); } return value; } - //~--- inner classes -------------------------------------------------------- - /** - * Class description - * - * - * @version Enter version here..., 14/03/18 - * @author Enter your name here... - */ - private static final class ClassAnnotation - { + private static final class ClassAnnotation { - /** - * Constructs ... - * - * - * @param elementName - * @param annotationClass - */ public ClassAnnotation(String elementName, - Class annotationClass) - { + Class annotationClass) { + this.elementName = elementName; this.annotationClass = annotationClass; } - //~--- fields ------------------------------------------------------------- - - /** Field description */ private final Class annotationClass; - - /** Field description */ private final String elementName; } } diff --git a/scm-annotations/src/main/java/sonia/scm/plugin/ExtensionPoint.java b/scm-annotations/src/main/java/sonia/scm/plugin/ExtensionPoint.java index 5417317627..b36a28f993 100644 --- a/scm-annotations/src/main/java/sonia/scm/plugin/ExtensionPoint.java +++ b/scm-annotations/src/main/java/sonia/scm/plugin/ExtensionPoint.java @@ -33,8 +33,6 @@ package sonia.scm.plugin; -//~--- JDK imports ------------------------------------------------------------ - import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/scm-core/src/main/java/sonia/scm/repository/NamespaceStrategy.java b/scm-core/src/main/java/sonia/scm/repository/NamespaceStrategy.java new file mode 100644 index 0000000000..f972956adf --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/NamespaceStrategy.java @@ -0,0 +1,8 @@ +package sonia.scm.repository; + +import sonia.scm.plugin.ExtensionPoint; + +@ExtensionPoint +public interface NamespaceStrategy { + String getNamespace(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceResolver.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceResolver.java index f0ed4c0814..d747bbdce0 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceResolver.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceResolver.java @@ -33,8 +33,6 @@ package sonia.scm.repository.spi; -//~--- non-JDK imports -------------------------------------------------------- - import sonia.scm.plugin.ExtensionPoint; import sonia.scm.repository.Repository; @@ -55,5 +53,5 @@ public interface RepositoryServiceResolver * * @return */ - public RepositoryServiceProvider reslove(Repository repository); + public RepositoryServiceProvider resolve(Repository repository); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java index 70609eee87..52c5171627 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java @@ -76,7 +76,7 @@ public class GitRepositoryServiceResolver implements RepositoryServiceResolver * @return */ @Override - public GitRepositoryServiceProvider reslove(Repository repository) + public GitRepositoryServiceProvider resolve(Repository repository) { GitRepositoryServiceProvider provider = null; diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java index 9b87991ae6..d322cb8e9f 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java @@ -82,7 +82,7 @@ public class HgRepositoryServiceResolver implements RepositoryServiceResolver * @return */ @Override - public HgRepositoryServiceProvider reslove(Repository repository) + public HgRepositoryServiceProvider resolve(Repository repository) { HgRepositoryServiceProvider provider = null; diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java index c46c6722be..d56398083e 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java @@ -76,7 +76,7 @@ public class SvnRepositoryServiceResolver implements RepositoryServiceResolver * @return */ @Override - public SvnRepositoryServiceProvider reslove(Repository repository) + public SvnRepositoryServiceProvider resolve(Repository repository) { SvnRepositoryServiceProvider provider = null; diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index a09de33465..700116d862 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -62,14 +62,7 @@ import sonia.scm.plugin.DefaultPluginLoader; import sonia.scm.plugin.DefaultPluginManager; 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.*; import sonia.scm.repository.api.HookContextFactory; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.repository.spi.HookEventFacade; @@ -360,6 +353,8 @@ public class ScmServletModule extends ServletModule // bind events // bind(LastModifiedUpdateListener.class); + + bind(NamespaceStrategy.class, DefaultNamespaceStrategy.class); } /** diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultNamespaceStrategy.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultNamespaceStrategy.java new file mode 100644 index 0000000000..ce6362ee9c --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultNamespaceStrategy.java @@ -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"; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java index 8ddb02d9ca..e0fccba8d5 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2010, Sebastian Sdorra * All rights reserved. - * + *

* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + *

* 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. + *

* 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. - * + *

* http://bitbucket.org/sdorra/scm-manager - * */ - package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- @@ -84,71 +82,53 @@ import javax.servlet.http.HttpServletRequest; * @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 handlerMap; + private final KeyGenerator keyGenerator; + private final RepositoryDAO repositoryDAO; + private final Set types; + private RepositoryMatcher repositoryMatcher; + private NamespaceStrategy namespaceStrategy; - //~--- constructors --------------------------------------------------------- - /** - * Constructs ... - * - * @param configuration - * @param contextProvider - * @param keyGenerator - * @param repositoryDAO - * @param handlerSet - * @param repositoryMatcher - */ @Inject public DefaultRepositoryManager(ScmConfiguration configuration, - SCMContextProvider contextProvider, KeyGenerator keyGenerator, - RepositoryDAO repositoryDAO, Set handlerSet, - RepositoryMatcher repositoryMatcher) - { + SCMContextProvider contextProvider, KeyGenerator keyGenerator, + RepositoryDAO repositoryDAO, Set handlerSet, + RepositoryMatcher repositoryMatcher, + NamespaceStrategy namespaceStrategy) { this.configuration = configuration; this.keyGenerator = keyGenerator; this.repositoryDAO = repositoryDAO; this.repositoryMatcher = repositoryMatcher; + 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); } } @@ -164,24 +144,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()); 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); } @@ -201,8 +179,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager */ @Override public void create(Repository repository) - throws RepositoryException, IOException - { + throws RepositoryException, IOException { create(repository, true); } @@ -217,31 +194,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")); } @@ -258,8 +229,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager */ @Override public void importRepository(Repository repository) - throws RepositoryException, IOException - { + throws RepositoryException, IOException { create(repository, false); } @@ -270,7 +240,8 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @param context */ @Override - public void init(SCMContextProvider context) {} + public void init(SCMContextProvider context) { + } /** * Method description @@ -283,10 +254,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()); } @@ -294,19 +263,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")); } @@ -323,20 +289,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")); } @@ -353,16 +315,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(); } @@ -379,15 +339,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(); } @@ -404,25 +362,21 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @return */ @Override - public Collection getAll(Comparator comparator) - { + public Collection getAll(Comparator comparator) { List repositories = Lists.newArrayList(); PermissionActionCheck 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); } @@ -436,8 +390,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @return */ @Override - public Collection getAll() - { + public Collection getAll() { return getAll(null); } @@ -454,23 +407,19 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager */ @Override public Collection getAll(Comparator comparator, - int start, int limit) - { + int start, int limit) { final PermissionActionCheck check = RepositoryPermissions.read(); return Util.createSubCollection(repositoryDAO.getAll(), comparator, - new CollectionAppender() - { - @Override - public void append(Collection collection, Repository item) - { - if (check.isPermitted(item)) - { - collection.add(item.clone()); + new CollectionAppender() { + @Override + public void append(Collection collection, Repository item) { + if (check.isPermitted(item)) { + collection.add(item.clone()); + } } - } - }, start, limit); + }, start, limit); } /** @@ -483,8 +432,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @return */ @Override - public Collection getAll(int start, int limit) - { + public Collection getAll(int start, int limit) { return getAll(null, start, limit); } @@ -495,14 +443,11 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @return */ @Override - public Collection getConfiguredTypes() - { + public Collection getConfiguredTypes() { List validTypes = Lists.newArrayList(); - for (RepositoryHandler handler : handlerMap.values()) - { - if (handler.isConfigured()) - { + for (RepositoryHandler handler : handlerMap.values()) { + if (handler.isConfigured()) { validTypes.add(handler.getType()); } } @@ -519,8 +464,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)); @@ -536,15 +480,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"); } @@ -553,16 +494,13 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager Repository repository = null; - if (handlerMap.containsKey(type)) - { + if (handlerMap.containsKey(type)) { Collection repositories = repositoryDAO.getAll(); PermissionActionCheck 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(); @@ -571,8 +509,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); } @@ -589,20 +526,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); @@ -621,8 +555,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @return */ @Override - public RepositoryHandler getHandler(String type) - { + public RepositoryHandler getHandler(String type) { return handlerMap.get(type); } @@ -633,8 +566,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @return */ @Override - public Long getLastModified() - { + public Long getLastModified() { return repositoryDAO.getLastModified(); } @@ -645,8 +577,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager * @return */ @Override - public Collection getTypes() - { + public Collection getTypes() { return types; } @@ -661,22 +592,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); } @@ -700,44 +628,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 handlerMap; - - /** Field description */ - private final KeyGenerator keyGenerator; - - /** Field description */ - private final RepositoryDAO repositoryDAO; - - /** Field description */ - private final Set types; - - /** Field description */ - private RepositoryMatcher repositoryMatcher; } diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java index 90a78e63c6..35c22ac483 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerPerfTest.java @@ -93,6 +93,8 @@ public class DefaultRepositoryManagerPerfTest { private final ScmConfiguration configuration = new ScmConfiguration(); private final KeyGenerator keyGenerator = new DefaultKeyGenerator(); + + private final NamespaceStrategy namespaceStrategy = new DefaultNamespaceStrategy(); @Mock private RepositoryHandler repositoryHandler; @@ -117,7 +119,8 @@ public class DefaultRepositoryManagerPerfTest { keyGenerator, repositoryDAO, handlerSet, - repositoryMatcher + repositoryMatcher, + namespaceStrategy ); setUpTestRepositories(); diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java index 8c60e45b04..6bafe5e717 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java @@ -539,10 +539,12 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase