mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-05 11:50:58 +01:00
Merged in feature/errorhandling (pull request #99)
Feature Error Handling
This commit is contained in:
@@ -1,11 +1,34 @@
|
||||
package sonia.scm;
|
||||
|
||||
public class AlreadyExistsException extends Exception {
|
||||
import java.util.List;
|
||||
|
||||
public AlreadyExistsException(String message) {
|
||||
super(message);
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
public class AlreadyExistsException extends ExceptionWithContext {
|
||||
|
||||
private static final String CODE = "FtR7UznKU1";
|
||||
|
||||
public AlreadyExistsException(ModelObject object) {
|
||||
this(singletonList(new ContextEntry(object.getClass(), object.getId())));
|
||||
}
|
||||
|
||||
public AlreadyExistsException() {
|
||||
public static AlreadyExistsException alreadyExists(ContextEntry.ContextBuilder builder) {
|
||||
return new AlreadyExistsException(builder.build());
|
||||
}
|
||||
|
||||
private AlreadyExistsException(List<ContextEntry> context) {
|
||||
super(context, createMessage(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return CODE;
|
||||
}
|
||||
|
||||
private static String createMessage(List<ContextEntry> context) {
|
||||
return context.stream()
|
||||
.map(c -> c.getType().toLowerCase() + " with id " + c.getId())
|
||||
.collect(joining(" in ", "", " already exists"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,34 @@
|
||||
package sonia.scm;
|
||||
|
||||
public class ConcurrentModificationException extends Exception {
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
public class ConcurrentModificationException extends ExceptionWithContext {
|
||||
|
||||
private static final String CODE = "2wR7UzpPG1";
|
||||
|
||||
public ConcurrentModificationException(Class type, String id) {
|
||||
this(Collections.singletonList(new ContextEntry(type, id)));
|
||||
}
|
||||
|
||||
public ConcurrentModificationException(String type, String id) {
|
||||
this(Collections.singletonList(new ContextEntry(type, id)));
|
||||
}
|
||||
|
||||
private ConcurrentModificationException(List<ContextEntry> context) {
|
||||
super(context, createMessage(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return CODE;
|
||||
}
|
||||
|
||||
private static String createMessage(List<ContextEntry> context) {
|
||||
return context.stream()
|
||||
.map(c -> c.getType().toLowerCase() + " with id " + c.getId())
|
||||
.collect(joining(" in ", "", " has been modified concurrently"));
|
||||
}
|
||||
}
|
||||
|
||||
84
scm-core/src/main/java/sonia/scm/ContextEntry.java
Normal file
84
scm-core/src/main/java/sonia/scm/ContextEntry.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package sonia.scm;
|
||||
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.util.AssertUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ContextEntry {
|
||||
private final String type;
|
||||
private final String id;
|
||||
|
||||
ContextEntry(Class type, String id) {
|
||||
this(type.getSimpleName(), id);
|
||||
}
|
||||
|
||||
ContextEntry(String type, String id) {
|
||||
AssertUtil.assertIsNotEmpty(type);
|
||||
AssertUtil.assertIsNotEmpty(id);
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public static class ContextBuilder {
|
||||
private final List<ContextEntry> context = new LinkedList<>();
|
||||
|
||||
public static List<ContextEntry> noContext() {
|
||||
return new ContextBuilder().build();
|
||||
}
|
||||
|
||||
public static List<ContextEntry> only(String type, String id) {
|
||||
return new ContextBuilder().in(type, id).build();
|
||||
}
|
||||
|
||||
public static ContextBuilder entity(Repository repository) {
|
||||
return new ContextBuilder().in(repository.getNamespaceAndName());
|
||||
}
|
||||
|
||||
public static ContextBuilder entity(NamespaceAndName namespaceAndName) {
|
||||
return new ContextBuilder().in(Repository.class, namespaceAndName.logString());
|
||||
}
|
||||
|
||||
public static ContextBuilder entity(Class type, String id) {
|
||||
return new ContextBuilder().in(type, id);
|
||||
}
|
||||
|
||||
public static ContextBuilder entity(String type, String id) {
|
||||
return new ContextBuilder().in(type, id);
|
||||
}
|
||||
|
||||
public ContextBuilder in(Repository repository) {
|
||||
return in(repository.getNamespaceAndName());
|
||||
}
|
||||
|
||||
public ContextBuilder in(NamespaceAndName namespaceAndName) {
|
||||
return this.in(Repository.class, namespaceAndName.logString());
|
||||
}
|
||||
|
||||
public ContextBuilder in(Class type, String id) {
|
||||
context.add(new ContextEntry(type, id));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContextBuilder in(String type, String id) {
|
||||
context.add(new ContextEntry(type, id));
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<ContextEntry> build() {
|
||||
return Collections.unmodifiableList(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
scm-core/src/main/java/sonia/scm/ExceptionWithContext.java
Normal file
26
scm-core/src/main/java/sonia/scm/ExceptionWithContext.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package sonia.scm;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
|
||||
public abstract class ExceptionWithContext extends RuntimeException {
|
||||
|
||||
private final List<ContextEntry> context;
|
||||
|
||||
public ExceptionWithContext(List<ContextEntry> context, String message) {
|
||||
super(message);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public ExceptionWithContext(List<ContextEntry> context, String message, Exception cause) {
|
||||
super(message, cause);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public List<ContextEntry> getContext() {
|
||||
return unmodifiableList(context);
|
||||
}
|
||||
|
||||
public abstract String getCode();
|
||||
}
|
||||
@@ -54,25 +54,21 @@ public interface HandlerBase<T extends TypedObject>
|
||||
*
|
||||
* @return The persisted object.
|
||||
*/
|
||||
T create(T object) throws AlreadyExistsException;
|
||||
T create(T object);
|
||||
|
||||
/**
|
||||
* Removes a persistent object.
|
||||
*
|
||||
*
|
||||
* @param object to delete
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void delete(T object) throws NotFoundException;
|
||||
void delete(T object);
|
||||
|
||||
/**
|
||||
* Modifies a persistent object.
|
||||
*
|
||||
*
|
||||
* @param object to modify
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void modify(T object) throws NotFoundException;
|
||||
void modify(T object);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public interface Manager<T extends ModelObject>
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
void refresh(T object) throws NotFoundException;
|
||||
void refresh(T object);
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ManagerDecorator<T extends ModelObject> implements Manager<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T create(T object) throws AlreadyExistsException {
|
||||
public T create(T object) {
|
||||
return decorated.create(object);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,38 @@
|
||||
package sonia.scm;
|
||||
|
||||
public class NotFoundException extends RuntimeException {
|
||||
public NotFoundException(String type, String id) {
|
||||
super(type + " with id '" + id + "' not found");
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
public class NotFoundException extends ExceptionWithContext {
|
||||
|
||||
private static final String CODE = "AGR7UzkhA1";
|
||||
|
||||
public NotFoundException(Class type, String id) {
|
||||
this(Collections.singletonList(new ContextEntry(type, id)));
|
||||
}
|
||||
|
||||
public NotFoundException() {
|
||||
public NotFoundException(String type, String id) {
|
||||
this(Collections.singletonList(new ContextEntry(type, id)));
|
||||
}
|
||||
|
||||
public static NotFoundException notFound(ContextEntry.ContextBuilder contextBuilder) {
|
||||
return new NotFoundException(contextBuilder.build());
|
||||
}
|
||||
|
||||
private NotFoundException(List<ContextEntry> context) {
|
||||
super(context, createMessage(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return CODE;
|
||||
}
|
||||
|
||||
private static String createMessage(List<ContextEntry> context) {
|
||||
return context.stream()
|
||||
.map(c -> c.getType().toLowerCase() + " with id " + c.getId())
|
||||
.collect(joining(" in ", "could not find ", ""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,33 +33,30 @@
|
||||
|
||||
package sonia.scm;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @version 1.6
|
||||
*/
|
||||
public class NotSupportedFeatuerException extends Exception
|
||||
{
|
||||
public class NotSupportedFeatureException extends ExceptionWithContext {
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = 256498734456613496L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
private static final String CODE = "9SR8G0kmU1";
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public NotSupportedFeatuerException() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public NotSupportedFeatuerException(String message)
|
||||
public NotSupportedFeatureException(String feature)
|
||||
{
|
||||
super(message);
|
||||
super(Collections.emptyList(),createMessage(feature));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return CODE;
|
||||
}
|
||||
|
||||
private static String createMessage(String feature) {
|
||||
return "feature " + feature + " is not supported by this repository";
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,6 @@ package sonia.scm.repository;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.repository.ImportResult.Builder;
|
||||
|
||||
import java.io.File;
|
||||
@@ -243,7 +242,7 @@ public abstract class AbstactImportHandler implements AdvancedImportHandler
|
||||
*/
|
||||
private void importRepository(RepositoryManager manager,
|
||||
String repositoryName)
|
||||
throws IOException, AlreadyExistsException {
|
||||
throws IOException {
|
||||
Repository repository =
|
||||
createRepository(getRepositoryDirectory(repositoryName), repositoryName);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ package sonia.scm.repository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.NotSupportedFeatuerException;
|
||||
import sonia.scm.NotSupportedFeatureException;
|
||||
import sonia.scm.SCMContextProvider;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
|
||||
@@ -165,13 +165,12 @@ public abstract class AbstractRepositoryHandler<C extends RepositoryConfig>
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws NotSupportedFeatuerException
|
||||
* @throws NotSupportedFeatureException
|
||||
*/
|
||||
@Override
|
||||
public ImportHandler getImportHandler() throws NotSupportedFeatuerException
|
||||
public ImportHandler getImportHandler() throws NotSupportedFeatureException
|
||||
{
|
||||
throw new NotSupportedFeatuerException(
|
||||
"import handler is not supported by this repository handler");
|
||||
throw new NotSupportedFeatureException("import");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.ConfigurationException;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.io.CommandResult;
|
||||
import sonia.scm.io.ExtendedCommand;
|
||||
import sonia.scm.io.FileSystem;
|
||||
@@ -81,14 +82,14 @@ public abstract class AbstractSimpleRepositoryHandler<C extends RepositoryConfig
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository create(Repository repository) throws AlreadyExistsException {
|
||||
public Repository create(Repository repository) {
|
||||
File directory = getDirectory(repository);
|
||||
|
||||
if (directory.exists()) {
|
||||
throw new AlreadyExistsException();
|
||||
throw new AlreadyExistsException(repository);
|
||||
}
|
||||
|
||||
checkPath(directory);
|
||||
checkPath(directory, repository);
|
||||
|
||||
try {
|
||||
fileSystem.create(directory);
|
||||
@@ -128,7 +129,7 @@ public abstract class AbstractSimpleRepositoryHandler<C extends RepositoryConfig
|
||||
try {
|
||||
fileSystem.destroy(directory);
|
||||
} catch (IOException e) {
|
||||
throw new InternalRepositoryException("could not delete repository directory", e);
|
||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", directory.toString()).in(repository), "could not delete repository directory", e);
|
||||
}
|
||||
cleanupEmptyDirectories(config.getRepositoryDirectory(),
|
||||
directory.getParentFile());
|
||||
@@ -201,7 +202,7 @@ public abstract class AbstractSimpleRepositoryHandler<C extends RepositoryConfig
|
||||
}
|
||||
|
||||
protected void create(Repository repository, File directory)
|
||||
throws IOException, AlreadyExistsException {
|
||||
throws IOException {
|
||||
ExtendedCommand cmd = buildCreateCommand(repository, directory);
|
||||
CommandResult result = cmd.execute();
|
||||
|
||||
@@ -256,9 +257,9 @@ public abstract class AbstractSimpleRepositoryHandler<C extends RepositoryConfig
|
||||
* Check path for existing repositories
|
||||
*
|
||||
* @param directory repository target directory
|
||||
* @throws AlreadyExistsException
|
||||
* @throws RuntimeException when the parent directory already is a repository
|
||||
*/
|
||||
private void checkPath(File directory) throws AlreadyExistsException {
|
||||
private void checkPath(File directory, Repository repository) {
|
||||
File repositoryDirectory = config.getRepositoryDirectory();
|
||||
File parent = directory.getParentFile();
|
||||
|
||||
@@ -266,9 +267,7 @@ public abstract class AbstractSimpleRepositoryHandler<C extends RepositoryConfig
|
||||
logger.trace("check {} for existing repository", parent);
|
||||
|
||||
if (isRepository(parent)) {
|
||||
logger.error("parent path {} is a repository", parent);
|
||||
|
||||
throw new AlreadyExistsException();
|
||||
throw new InternalRepositoryException(repository, "parent path " + parent + " is a repository");
|
||||
}
|
||||
|
||||
parent = parent.getParentFile();
|
||||
|
||||
@@ -1,15 +1,34 @@
|
||||
package sonia.scm.repository;
|
||||
|
||||
public class InternalRepositoryException extends RuntimeException {
|
||||
public InternalRepositoryException(Throwable ex) {
|
||||
super(ex);
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.ExceptionWithContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InternalRepositoryException extends ExceptionWithContext {
|
||||
|
||||
public InternalRepositoryException(ContextEntry.ContextBuilder context, String message) {
|
||||
this(context, message, null);
|
||||
}
|
||||
|
||||
public InternalRepositoryException(String msg, Exception ex) {
|
||||
super(msg, ex);
|
||||
public InternalRepositoryException(ContextEntry.ContextBuilder context, String message, Exception cause) {
|
||||
this(context.build(), message, cause);
|
||||
}
|
||||
|
||||
public InternalRepositoryException(String message) {
|
||||
super(message);
|
||||
public InternalRepositoryException(Repository repository, String message) {
|
||||
this(ContextEntry.ContextBuilder.entity(repository), message, null);
|
||||
}
|
||||
|
||||
public InternalRepositoryException(Repository repository, String message, Exception cause) {
|
||||
this(ContextEntry.ContextBuilder.entity(repository), message, cause);
|
||||
}
|
||||
|
||||
public InternalRepositoryException(List<ContextEntry> context, String message, Exception cause) {
|
||||
super(context, message, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,13 @@ public class NamespaceAndName implements Comparable<NamespaceAndName> {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String logString() {
|
||||
return getNamespace() + "/" + getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getNamespace() + "/" + getName();
|
||||
return logString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/**
|
||||
* 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 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.
|
||||
*
|
||||
* 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
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 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.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
/**
|
||||
* Signals that the specified path could be found.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class PathNotFoundException extends NotFoundException
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = 4629690181172951809L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a new {@link PathNotFoundException}
|
||||
* with the specified path.
|
||||
*
|
||||
*
|
||||
* @param path path which could not be found
|
||||
*/
|
||||
public PathNotFoundException(String path)
|
||||
{
|
||||
super("path", Util.nonNull(path));
|
||||
this.path = Util.nonNull(path);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return the path which could not be found.
|
||||
*
|
||||
*
|
||||
* @return path which could not be found
|
||||
*/
|
||||
public String getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String path;
|
||||
}
|
||||
@@ -36,7 +36,7 @@ package sonia.scm.repository;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.Handler;
|
||||
import sonia.scm.NotSupportedFeatuerException;
|
||||
import sonia.scm.NotSupportedFeatureException;
|
||||
import sonia.scm.plugin.ExtensionPoint;
|
||||
|
||||
/**
|
||||
@@ -70,9 +70,9 @@ public interface RepositoryHandler
|
||||
* @return {@link ImportHandler} for the repository type of this handler
|
||||
* @since 1.12
|
||||
*
|
||||
* @throws NotSupportedFeatuerException
|
||||
* @throws NotSupportedFeatureException
|
||||
*/
|
||||
public ImportHandler getImportHandler() throws NotSupportedFeatuerException;
|
||||
public ImportHandler getImportHandler() throws NotSupportedFeatureException;
|
||||
|
||||
/**
|
||||
* Returns informations about the version of the RepositoryHandler.
|
||||
|
||||
@@ -35,7 +35,6 @@ package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.TypeManager;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -73,7 +72,7 @@ public interface RepositoryManager
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void importRepository(Repository repository) throws IOException, AlreadyExistsException;
|
||||
public void importRepository(Repository repository) throws IOException;
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.ManagerDecorator;
|
||||
import sonia.scm.Type;
|
||||
|
||||
@@ -82,7 +81,7 @@ public class RepositoryManagerDecorator
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void importRepository(Repository repository) throws IOException, AlreadyExistsException {
|
||||
public void importRepository(Repository repository) throws IOException {
|
||||
decorated.importRepository(repository);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* 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 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.
|
||||
*
|
||||
* 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
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 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.repository;
|
||||
|
||||
import sonia.scm.NotFoundException;
|
||||
|
||||
/**
|
||||
* Signals that the specified {@link Repository} could be found.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.6
|
||||
*/
|
||||
public class RepositoryNotFoundException extends NotFoundException
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -6583078808900520166L;
|
||||
private static final String TYPE_REPOSITORY = "repository";
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a new {@link RepositoryNotFoundException} with null as its
|
||||
* error detail message.
|
||||
*
|
||||
*/
|
||||
public RepositoryNotFoundException(Repository repository) {
|
||||
super(TYPE_REPOSITORY, repository.getName() + "/" + repository.getNamespace());
|
||||
}
|
||||
|
||||
public RepositoryNotFoundException(String repositoryId) {
|
||||
super(TYPE_REPOSITORY, repositoryId);
|
||||
}
|
||||
|
||||
public RepositoryNotFoundException(NamespaceAndName namespaceAndName) {
|
||||
super(TYPE_REPOSITORY, namespaceAndName.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* 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 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.
|
||||
*
|
||||
* 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
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 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.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
/**
|
||||
* Signals that the specified revision could be found.
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class RevisionNotFoundException extends NotFoundException {
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -5594008535358811998L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a new {@link RevisionNotFoundException}
|
||||
* with the specified revision.
|
||||
*
|
||||
*
|
||||
* @param revision revision which could not be found
|
||||
*/
|
||||
public RevisionNotFoundException(String revision)
|
||||
{
|
||||
super("revision", revision);
|
||||
this.revision = Util.nonNull(revision);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return the revision which could not be found.
|
||||
*
|
||||
*
|
||||
* @return revision which could not be found
|
||||
*/
|
||||
public String getRevision()
|
||||
{
|
||||
return revision;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String revision;
|
||||
}
|
||||
@@ -38,7 +38,6 @@ package sonia.scm.repository.api;
|
||||
import com.google.common.base.Objects;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.cache.Cache;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.repository.BrowserResult;
|
||||
@@ -46,7 +45,6 @@ import sonia.scm.repository.FileObject;
|
||||
import sonia.scm.repository.PreProcessorUtil;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryCacheKey;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.spi.BrowseCommand;
|
||||
import sonia.scm.repository.spi.BrowseCommandRequest;
|
||||
|
||||
@@ -136,7 +134,7 @@ public final class BrowseCommandBuilder
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public BrowserResult getBrowserResult() throws IOException, NotFoundException {
|
||||
public BrowserResult getBrowserResult() throws IOException {
|
||||
BrowserResult result = null;
|
||||
|
||||
if (disableCache)
|
||||
|
||||
@@ -37,9 +37,7 @@ import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.spi.CatCommand;
|
||||
import sonia.scm.repository.spi.CatCommandRequest;
|
||||
import sonia.scm.util.IOUtil;
|
||||
@@ -107,7 +105,7 @@ public final class CatCommandBuilder
|
||||
* @param outputStream output stream for the content
|
||||
* @param path file path
|
||||
*/
|
||||
public void retriveContent(OutputStream outputStream, String path) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public void retriveContent(OutputStream outputStream, String path) throws IOException {
|
||||
getCatResult(outputStream, path);
|
||||
}
|
||||
|
||||
@@ -116,7 +114,7 @@ public final class CatCommandBuilder
|
||||
*
|
||||
* @param path file path
|
||||
*/
|
||||
public InputStream getStream(String path) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public InputStream getStream(String path) throws IOException {
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(path),
|
||||
"path is required");
|
||||
|
||||
@@ -139,7 +137,7 @@ public final class CatCommandBuilder
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public String getContent(String path) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public String getContent(String path) throws IOException {
|
||||
String content = null;
|
||||
ByteArrayOutputStream baos = null;
|
||||
|
||||
@@ -186,7 +184,7 @@ public final class CatCommandBuilder
|
||||
* @throws IOException
|
||||
*/
|
||||
private void getCatResult(OutputStream outputStream, String path)
|
||||
throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
throws IOException {
|
||||
Preconditions.checkNotNull(outputStream, "OutputStream is required");
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(path),
|
||||
"path is required");
|
||||
|
||||
@@ -38,7 +38,6 @@ package sonia.scm.repository.api;
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.spi.DiffCommand;
|
||||
import sonia.scm.repository.spi.DiffCommandRequest;
|
||||
import sonia.scm.util.IOUtil;
|
||||
@@ -104,7 +103,7 @@ public final class DiffCommandBuilder
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public DiffCommandBuilder retrieveContent(OutputStream outputStream) throws IOException, RevisionNotFoundException {
|
||||
public DiffCommandBuilder retrieveContent(OutputStream outputStream) throws IOException {
|
||||
getDiffResult(outputStream);
|
||||
|
||||
return this;
|
||||
@@ -119,7 +118,7 @@ public final class DiffCommandBuilder
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public String getContent() throws IOException, RevisionNotFoundException {
|
||||
public String getContent() throws IOException {
|
||||
String content = null;
|
||||
ByteArrayOutputStream baos = null;
|
||||
|
||||
@@ -199,7 +198,7 @@ public final class DiffCommandBuilder
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void getDiffResult(OutputStream outputStream) throws IOException, RevisionNotFoundException {
|
||||
private void getDiffResult(OutputStream outputStream) throws IOException {
|
||||
Preconditions.checkNotNull(outputStream, "OutputStream is required");
|
||||
Preconditions.checkArgument(request.isValid(),
|
||||
"path and/or revision is required");
|
||||
|
||||
@@ -46,7 +46,6 @@ import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.PreProcessorUtil;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryCacheKey;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.spi.LogCommand;
|
||||
import sonia.scm.repository.spi.LogCommandRequest;
|
||||
|
||||
@@ -165,7 +164,7 @@ public final class LogCommandBuilder
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public Changeset getChangeset(String id) throws IOException, RevisionNotFoundException {
|
||||
public Changeset getChangeset(String id) throws IOException {
|
||||
Changeset changeset;
|
||||
|
||||
if (disableCache)
|
||||
@@ -224,7 +223,7 @@ public final class LogCommandBuilder
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public ChangesetPagingResult getChangesets() throws IOException, RevisionNotFoundException {
|
||||
public ChangesetPagingResult getChangesets() throws IOException {
|
||||
ChangesetPagingResult cpr;
|
||||
|
||||
if (disableCache)
|
||||
|
||||
@@ -13,7 +13,6 @@ import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.PreProcessorUtil;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryCacheKey;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.spi.ModificationsCommand;
|
||||
import sonia.scm.repository.spi.ModificationsCommandRequest;
|
||||
|
||||
@@ -67,7 +66,7 @@ public final class ModificationsCommandBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Modifications getModifications() throws IOException, RevisionNotFoundException {
|
||||
public Modifications getModifications() throws IOException {
|
||||
Modifications modifications;
|
||||
if (disableCache) {
|
||||
log.info("Get modifications for {} with disabled cache", request);
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.google.inject.Singleton;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.HandlerEventType;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.cache.Cache;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
@@ -57,7 +58,6 @@ import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryCacheKeyPredicate;
|
||||
import sonia.scm.repository.RepositoryEvent;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.repository.spi.RepositoryServiceResolver;
|
||||
@@ -65,6 +65,9 @@ import sonia.scm.security.ScmSecurityException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -161,7 +164,7 @@ public final class RepositoryServiceFactory
|
||||
* @return a implementation of RepositoryService
|
||||
* for the given type of repository
|
||||
*
|
||||
* @throws RepositoryNotFoundException if no repository
|
||||
* @throws NotFoundException if no repository
|
||||
* with the given id is available
|
||||
* @throws RepositoryServiceNotFoundException if no repository service
|
||||
* implementation for this kind of repository is available
|
||||
@@ -169,7 +172,7 @@ public final class RepositoryServiceFactory
|
||||
* @throws ScmSecurityException if current user has not read permissions
|
||||
* for that repository
|
||||
*/
|
||||
public RepositoryService create(String repositoryId) throws RepositoryNotFoundException {
|
||||
public RepositoryService create(String repositoryId) {
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(repositoryId),
|
||||
"a non empty repositoryId is required");
|
||||
|
||||
@@ -177,7 +180,7 @@ public final class RepositoryServiceFactory
|
||||
|
||||
if (repository == null)
|
||||
{
|
||||
throw new RepositoryNotFoundException(repositoryId);
|
||||
throw new NotFoundException(Repository.class, repositoryId);
|
||||
}
|
||||
|
||||
return create(repository);
|
||||
@@ -192,7 +195,7 @@ public final class RepositoryServiceFactory
|
||||
* @return a implementation of RepositoryService
|
||||
* for the given type of repository
|
||||
*
|
||||
* @throws RepositoryNotFoundException if no repository
|
||||
* @throws NotFoundException if no repository
|
||||
* with the given id is available
|
||||
* @throws RepositoryServiceNotFoundException if no repository service
|
||||
* implementation for this kind of repository is available
|
||||
@@ -201,7 +204,6 @@ public final class RepositoryServiceFactory
|
||||
* for that repository
|
||||
*/
|
||||
public RepositoryService create(NamespaceAndName namespaceAndName)
|
||||
throws RepositoryNotFoundException
|
||||
{
|
||||
Preconditions.checkArgument(namespaceAndName != null,
|
||||
"a non empty namespace and name is required");
|
||||
@@ -210,7 +212,7 @@ public final class RepositoryServiceFactory
|
||||
|
||||
if (repository == null)
|
||||
{
|
||||
throw new RepositoryNotFoundException(namespaceAndName);
|
||||
throw notFound(entity(namespaceAndName));
|
||||
}
|
||||
|
||||
return create(repository);
|
||||
|
||||
@@ -35,7 +35,6 @@ package sonia.scm.repository.spi;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.BrowserResult;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -60,5 +59,5 @@ public interface BrowseCommand
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
BrowserResult getBrowserResult(BrowseCommandRequest request) throws IOException, NotFoundException;
|
||||
BrowserResult getBrowserResult(BrowseCommandRequest request) throws IOException;
|
||||
}
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -47,7 +44,7 @@ import java.io.OutputStream;
|
||||
*/
|
||||
public interface CatCommand {
|
||||
|
||||
void getCatResult(CatCommandRequest request, OutputStream output) throws IOException, RevisionNotFoundException, PathNotFoundException;
|
||||
void getCatResult(CatCommandRequest request, OutputStream output) throws IOException;
|
||||
|
||||
InputStream getCatResultStream(CatCommandRequest request) throws IOException, RevisionNotFoundException, PathNotFoundException;
|
||||
InputStream getCatResultStream(CatCommandRequest request) throws IOException;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@@ -56,5 +54,5 @@ public interface DiffCommand
|
||||
* @throws IOException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public void getDiffResult(DiffCommandRequest request, OutputStream output) throws IOException, RevisionNotFoundException;
|
||||
public void getDiffResult(DiffCommandRequest request, OutputStream output) throws IOException;
|
||||
}
|
||||
|
||||
@@ -40,10 +40,12 @@ import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryHookEvent;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.api.HookContext;
|
||||
import sonia.scm.repository.api.HookContextFactory;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -71,18 +73,18 @@ public final class HookEventFacade
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
public HookEventHandler handle(String id) throws RepositoryNotFoundException {
|
||||
public HookEventHandler handle(String id) {
|
||||
return handle(repositoryManagerProvider.get().get(id));
|
||||
}
|
||||
|
||||
public HookEventHandler handle(NamespaceAndName namespaceAndName) throws RepositoryNotFoundException {
|
||||
public HookEventHandler handle(NamespaceAndName namespaceAndName) {
|
||||
return handle(repositoryManagerProvider.get().get(namespaceAndName));
|
||||
}
|
||||
|
||||
public HookEventHandler handle(Repository repository) throws RepositoryNotFoundException {
|
||||
public HookEventHandler handle(Repository repository) {
|
||||
if (repository == null)
|
||||
{
|
||||
throw new RepositoryNotFoundException(repository);
|
||||
throw notFound(entity(repository));
|
||||
}
|
||||
|
||||
return new HookEventHandler(repositoryManagerProvider.get(),
|
||||
|
||||
@@ -37,7 +37,6 @@ package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -50,7 +49,7 @@ import java.io.IOException;
|
||||
*/
|
||||
public interface LogCommand {
|
||||
|
||||
Changeset getChangeset(String id) throws IOException, RevisionNotFoundException;
|
||||
Changeset getChangeset(String id) throws IOException;
|
||||
|
||||
ChangesetPagingResult getChangesets(LogCommandRequest request) throws IOException, RevisionNotFoundException;
|
||||
ChangesetPagingResult getChangesets(LogCommandRequest request) throws IOException;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -46,8 +45,8 @@ import java.io.IOException;
|
||||
*/
|
||||
public interface ModificationsCommand {
|
||||
|
||||
Modifications getModifications(String revision) throws IOException, RevisionNotFoundException;
|
||||
Modifications getModifications(String revision) throws IOException;
|
||||
|
||||
Modifications getModifications(ModificationsCommandRequest request) throws IOException, RevisionNotFoundException;
|
||||
Modifications getModifications(ModificationsCommandRequest request) throws IOException;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
package sonia.scm.user;
|
||||
|
||||
public class ChangePasswordNotAllowedException extends RuntimeException {
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.ExceptionWithContext;
|
||||
|
||||
public class ChangePasswordNotAllowedException extends ExceptionWithContext {
|
||||
|
||||
private static final String CODE = "9BR7qpDAe1";
|
||||
public static final String WRONG_USER_TYPE = "User of type %s are not allowed to change password";
|
||||
|
||||
public ChangePasswordNotAllowedException(String type) {
|
||||
super(String.format(WRONG_USER_TYPE, type));
|
||||
public ChangePasswordNotAllowedException(ContextEntry.ContextBuilder context, String type) {
|
||||
super(context.build(), String.format(WRONG_USER_TYPE, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return CODE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
package sonia.scm.user;
|
||||
|
||||
public class InvalidPasswordException extends RuntimeException {
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.ExceptionWithContext;
|
||||
|
||||
public InvalidPasswordException() {
|
||||
super("The given Password does not match with the stored one.");
|
||||
public class InvalidPasswordException extends ExceptionWithContext {
|
||||
|
||||
private static final String CODE = "8YR7aawFW1";
|
||||
|
||||
public InvalidPasswordException(ContextEntry.ContextBuilder context) {
|
||||
super(context.build(), "The given old password does not match with the stored one.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return CODE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ public class VndMediaType {
|
||||
|
||||
public static final String ME = PREFIX + "me" + SUFFIX;
|
||||
public static final String SOURCE = PREFIX + "source" + SUFFIX;
|
||||
public static final String ERROR_TYPE = PREFIX + "error" + SUFFIX;
|
||||
|
||||
private VndMediaType() {
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.group.GroupNames;
|
||||
@@ -132,7 +131,7 @@ public class SyncingRealmHelperTest {
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testStoreGroupCreate() throws AlreadyExistsException {
|
||||
public void testStoreGroupCreate() {
|
||||
Group group = new Group("unit-test", "heartOfGold");
|
||||
|
||||
helper.store(group);
|
||||
@@ -143,7 +142,7 @@ public class SyncingRealmHelperTest {
|
||||
* Tests {@link SyncingRealmHelper#store(Group)}.
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testStoreGroupFailure() throws AlreadyExistsException {
|
||||
public void testStoreGroupFailure() {
|
||||
Group group = new Group("unit-test", "heartOfGold");
|
||||
|
||||
doThrow(AlreadyExistsException.class).when(groupManager).create(group);
|
||||
@@ -169,7 +168,7 @@ public class SyncingRealmHelperTest {
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testStoreUserCreate() throws AlreadyExistsException {
|
||||
public void testStoreUserCreate() {
|
||||
User user = new User("tricia");
|
||||
|
||||
helper.store(user);
|
||||
@@ -180,7 +179,7 @@ public class SyncingRealmHelperTest {
|
||||
* Tests {@link SyncingRealmHelper#store(User)} with a thrown {@link AlreadyExistsException}.
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testStoreUserFailure() throws AlreadyExistsException {
|
||||
public void testStoreUserFailure() {
|
||||
User user = new User("tricia");
|
||||
|
||||
doThrow(AlreadyExistsException.class).when(userManager).create(user);
|
||||
|
||||
@@ -56,6 +56,7 @@ import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
import sonia.scm.web.GitUserAgentProvider;
|
||||
@@ -204,7 +205,7 @@ public final class GitUtil
|
||||
}
|
||||
catch (GitAPIException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not fetch", ex);
|
||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("remote", directory.toString()).in(remoteRepository), "could not fetch", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ public abstract class AbstractGitIncomingOutgoingCommand
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute incoming command", ex);
|
||||
throw new InternalRepositoryException(repository, "could not execute incoming command", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -200,13 +200,7 @@ public abstract class AbstractGitIncomingOutgoingCommand
|
||||
{
|
||||
if (e.getKey().startsWith(prefix))
|
||||
{
|
||||
if (ref != null)
|
||||
{
|
||||
throw new InternalRepositoryException("could not find remote branch");
|
||||
}
|
||||
|
||||
ref = e.getValue();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ public abstract class AbstractGitPushOrPullCommand extends AbstractGitCommand
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute push/pull command", ex);
|
||||
throw new InternalRepositoryException(repository, "could not execute push/pull command", ex);
|
||||
}
|
||||
|
||||
return counter;
|
||||
|
||||
@@ -55,6 +55,8 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -108,9 +110,8 @@ public class GitBlameCommand extends AbstractGitCommand implements BlameCommand
|
||||
|
||||
if (gitBlameResult == null)
|
||||
{
|
||||
throw new InternalRepositoryException(
|
||||
"could not create blame result for path ".concat(
|
||||
request.getPath()));
|
||||
throw new InternalRepositoryException(entity("path", request.getPath()).in(repository),
|
||||
"could not create blame result for path");
|
||||
}
|
||||
|
||||
List<BlameLine> blameLines = new ArrayList<BlameLine>();
|
||||
@@ -150,7 +151,7 @@ public class GitBlameCommand extends AbstractGitCommand implements BlameCommand
|
||||
}
|
||||
catch (GitAPIException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not create blame view", ex);
|
||||
throw new InternalRepositoryException(repository, "could not create blame view", ex);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -102,7 +102,7 @@ public class GitBranchesCommand extends AbstractGitCommand
|
||||
}
|
||||
catch (GitAPIException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not read branches", ex);
|
||||
throw new InternalRepositoryException(repository, "could not read branches", ex);
|
||||
}
|
||||
|
||||
return branches;
|
||||
|
||||
@@ -55,9 +55,7 @@ import sonia.scm.repository.BrowserResult;
|
||||
import sonia.scm.repository.FileObject;
|
||||
import sonia.scm.repository.GitSubModuleParser;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.SubRepository;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
@@ -104,7 +102,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public BrowserResult getBrowserResult(BrowseCommandRequest request)
|
||||
throws IOException, NotFoundException {
|
||||
throws IOException {
|
||||
logger.debug("try to create browse result for {}", request);
|
||||
|
||||
BrowserResult result;
|
||||
@@ -166,7 +164,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
*/
|
||||
private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo,
|
||||
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk)
|
||||
throws IOException, RevisionNotFoundException {
|
||||
throws IOException {
|
||||
|
||||
FileObject file = new FileObject();
|
||||
|
||||
@@ -258,7 +256,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
return result;
|
||||
}
|
||||
|
||||
private FileObject getEntry(org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId) throws IOException, NotFoundException {
|
||||
private FileObject getEntry(org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId) throws IOException {
|
||||
RevWalk revWalk = null;
|
||||
TreeWalk treeWalk = null;
|
||||
|
||||
@@ -309,7 +307,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
return Strings.isNullOrEmpty(request.getPath()) || "/".equals(request.getPath());
|
||||
}
|
||||
|
||||
private FileObject findChildren(FileObject parent, org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, NotFoundException {
|
||||
private FileObject findChildren(FileObject parent, org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException {
|
||||
List<FileObject> files = Lists.newArrayList();
|
||||
while (treeWalk.next())
|
||||
{
|
||||
@@ -337,7 +335,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
}
|
||||
|
||||
private FileObject findFirstMatch(org.eclipse.jgit.lib.Repository repo,
|
||||
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, NotFoundException {
|
||||
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException {
|
||||
String[] pathElements = request.getPath().split("/");
|
||||
int currentDepth = 0;
|
||||
int limit = pathElements.length;
|
||||
@@ -363,7 +361,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
private Map<String,
|
||||
SubRepository> getSubRepositories(org.eclipse.jgit.lib.Repository repo,
|
||||
ObjectId revision)
|
||||
throws IOException, RevisionNotFoundException {
|
||||
throws IOException {
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("read submodules of {} at {}", repository.getName(),
|
||||
@@ -377,7 +375,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
PATH_MODULES, baos);
|
||||
subRepositories = GitSubModuleParser.parse(baos.toString());
|
||||
}
|
||||
catch (PathNotFoundException ex)
|
||||
catch (NotFoundException ex)
|
||||
{
|
||||
logger.trace("could not find .gitmodules", ex);
|
||||
subRepositories = Collections.EMPTY_MAP;
|
||||
@@ -388,7 +386,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
|
||||
private SubRepository getSubRepository(org.eclipse.jgit.lib.Repository repo,
|
||||
ObjectId revId, String path)
|
||||
throws IOException, RevisionNotFoundException {
|
||||
throws IOException {
|
||||
Map<String, SubRepository> subRepositories = subrepositoryCache.get(revId);
|
||||
|
||||
if (subRepositories == null)
|
||||
|
||||
@@ -45,8 +45,6 @@ import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
import java.io.Closeable;
|
||||
@@ -55,6 +53,9 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
|
||||
public class GitCatCommand extends AbstractGitCommand implements CatCommand {
|
||||
|
||||
@@ -65,7 +66,7 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCatResult(CatCommandRequest request, OutputStream output) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public void getCatResult(CatCommandRequest request, OutputStream output) throws IOException {
|
||||
logger.debug("try to read content for {}", request);
|
||||
try (ClosableObjectLoaderContainer closableObjectLoaderContainer = getLoader(request)) {
|
||||
closableObjectLoaderContainer.objectLoader.copyTo(output);
|
||||
@@ -73,24 +74,24 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getCatResultStream(CatCommandRequest request) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public InputStream getCatResultStream(CatCommandRequest request) throws IOException {
|
||||
logger.debug("try to read content for {}", request);
|
||||
return new InputStreamWrapper(getLoader(request));
|
||||
}
|
||||
|
||||
void getContent(org.eclipse.jgit.lib.Repository repo, ObjectId revId, String path, OutputStream output) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
void getContent(org.eclipse.jgit.lib.Repository repo, ObjectId revId, String path, OutputStream output) throws IOException {
|
||||
try (ClosableObjectLoaderContainer closableObjectLoaderContainer = getLoader(repo, revId, path)) {
|
||||
closableObjectLoaderContainer.objectLoader.copyTo(output);
|
||||
}
|
||||
}
|
||||
|
||||
private ClosableObjectLoaderContainer getLoader(CatCommandRequest request) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
private ClosableObjectLoaderContainer getLoader(CatCommandRequest request) throws IOException {
|
||||
org.eclipse.jgit.lib.Repository repo = open();
|
||||
ObjectId revId = getCommitOrDefault(repo, request.getRevision());
|
||||
return getLoader(repo, revId, request.getPath());
|
||||
}
|
||||
|
||||
private ClosableObjectLoaderContainer getLoader(Repository repo, ObjectId revId, String path) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
private ClosableObjectLoaderContainer getLoader(Repository repo, ObjectId revId, String path) throws IOException {
|
||||
TreeWalk treeWalk = new TreeWalk(repo);
|
||||
treeWalk.setRecursive(Util.nonNull(path).contains("/"));
|
||||
|
||||
@@ -102,7 +103,7 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand {
|
||||
try {
|
||||
entry = revWalk.parseCommit(revId);
|
||||
} catch (MissingObjectException e) {
|
||||
throw new RevisionNotFoundException(revId.getName());
|
||||
throw notFound(entity("Revision", revId.getName()).in(repository));
|
||||
}
|
||||
RevTree revTree = entry.getTree();
|
||||
|
||||
@@ -120,7 +121,7 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand {
|
||||
|
||||
return new ClosableObjectLoaderContainer(loader, treeWalk, revWalk);
|
||||
} else {
|
||||
throw new PathNotFoundException(path);
|
||||
throw notFound(entity("Path", path).in("Revision", revId.getName()).in(repository));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.GitChangesetConverter;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -62,6 +61,9 @@ import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -86,7 +88,6 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
||||
*
|
||||
* @param context
|
||||
* @param repository
|
||||
* @param repositoryDirectory
|
||||
*/
|
||||
GitLogCommand(GitContext context, sonia.scm.repository.Repository repository)
|
||||
{
|
||||
@@ -163,7 +164,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ChangesetPagingResult getChangesets(LogCommandRequest request) throws RevisionNotFoundException {
|
||||
public ChangesetPagingResult getChangesets(LogCommandRequest request) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("fetch changesets for request: {}", request);
|
||||
}
|
||||
@@ -261,11 +262,11 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
||||
}
|
||||
catch (MissingObjectException e)
|
||||
{
|
||||
throw new RevisionNotFoundException(e.getObjectId().name());
|
||||
throw notFound(entity("Revision", e.getObjectId().getName()).in(repository));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not create change log", ex);
|
||||
throw new InternalRepositoryException(repository, "could not create change log", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -17,6 +17,8 @@ import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class GitModificationsCommand extends AbstractGitCommand implements ModificationsCommand {
|
||||
@@ -26,7 +28,7 @@ public class GitModificationsCommand extends AbstractGitCommand implements Modif
|
||||
}
|
||||
|
||||
private Modifications createModifications(TreeWalk treeWalk, RevCommit commit, RevWalk revWalk, String revision)
|
||||
throws IOException, UnsupportedModificationTypeException {
|
||||
throws IOException {
|
||||
treeWalk.reset();
|
||||
treeWalk.setRecursive(true);
|
||||
if (commit.getParentCount() > 0) {
|
||||
@@ -73,12 +75,7 @@ public class GitModificationsCommand extends AbstractGitCommand implements Modif
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
log.error("could not open repository", ex);
|
||||
throw new InternalRepositoryException(ex);
|
||||
|
||||
} catch (UnsupportedModificationTypeException ex) {
|
||||
log.error("Unsupported modification type", ex);
|
||||
throw new InternalRepositoryException(ex);
|
||||
|
||||
throw new InternalRepositoryException(entity(repository), "could not open repository", ex);
|
||||
} finally {
|
||||
GitUtil.release(revWalk);
|
||||
GitUtil.close(gitRepository);
|
||||
@@ -100,7 +97,7 @@ public class GitModificationsCommand extends AbstractGitCommand implements Modif
|
||||
} else if (type == DiffEntry.ChangeType.DELETE) {
|
||||
modifications.getRemoved().add(entry.getOldPath());
|
||||
} else {
|
||||
throw new UnsupportedModificationTypeException(MessageFormat.format("The modification type: {0} is not supported.", type));
|
||||
throw new UnsupportedModificationTypeException(entity(repository), MessageFormat.format("The modification type: {0} is not supported.", type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ public class GitPullCommand extends AbstractGitPushOrPullCommand
|
||||
}
|
||||
catch (GitAPIException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("error durring pull", ex);
|
||||
throw new InternalRepositoryException(repository, "error during pull", ex);
|
||||
}
|
||||
|
||||
return response;
|
||||
|
||||
@@ -95,7 +95,7 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand
|
||||
}
|
||||
catch (GitAPIException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not read tags from repository", ex);
|
||||
throw new InternalRepositoryException(repository, "could not read tags from repository", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
|
||||
public class UnsupportedModificationTypeException extends InternalRepositoryException {
|
||||
public UnsupportedModificationTypeException(String message) {
|
||||
super(message);
|
||||
public UnsupportedModificationTypeException(ContextEntry.ContextBuilder entity, String message) {
|
||||
super(entity, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import org.junit.Test;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.BrowserResult;
|
||||
import sonia.scm.repository.FileObject;
|
||||
import sonia.scm.repository.GitConstants;
|
||||
@@ -54,7 +53,7 @@ import static org.junit.Assert.assertTrue;
|
||||
public class GitBrowseCommandTest extends AbstractGitCommandTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetFile() throws IOException, NotFoundException {
|
||||
public void testDefaultBranch() throws IOException {
|
||||
BrowseCommandRequest request = new BrowseCommandRequest();
|
||||
request.setPath("a.txt");
|
||||
BrowserResult result = createCommand().getBrowserResult(request);
|
||||
@@ -63,7 +62,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultDefaultBranch() throws IOException, NotFoundException {
|
||||
public void testDefaultDefaultBranch() throws IOException {
|
||||
// without default branch, the repository head should be used
|
||||
FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile();
|
||||
assertNotNull(root);
|
||||
@@ -78,7 +77,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitDefaultBranch() throws IOException, NotFoundException {
|
||||
public void testExplicitDefaultBranch() throws IOException {
|
||||
repository.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "test-branch");
|
||||
|
||||
FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile();
|
||||
@@ -91,7 +90,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrowse() throws IOException, NotFoundException {
|
||||
public void testBrowse() throws IOException {
|
||||
FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile();
|
||||
assertNotNull(root);
|
||||
|
||||
@@ -113,7 +112,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrowseSubDirectory() throws IOException, NotFoundException {
|
||||
public void testBrowseSubDirectory() throws IOException {
|
||||
BrowseCommandRequest request = new BrowseCommandRequest();
|
||||
|
||||
request.setPath("c");
|
||||
@@ -143,7 +142,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecursive() throws IOException, NotFoundException {
|
||||
public void testRecusive() throws IOException {
|
||||
BrowseCommandRequest request = new BrowseCommandRequest();
|
||||
|
||||
request.setRecursive(true);
|
||||
|
||||
@@ -32,10 +32,13 @@
|
||||
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.GitConstants;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -51,9 +54,12 @@ import static org.junit.Assert.assertEquals;
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class GitCatCommandTest extends AbstractGitCommandTestBase {
|
||||
|
||||
|
||||
@Rule
|
||||
public final ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testDefaultBranch() throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public void testDefaultBranch() throws IOException {
|
||||
// without default branch, the repository head should be used
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
request.setPath("a.txt");
|
||||
@@ -66,7 +72,7 @@ public class GitCatCommandTest extends AbstractGitCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCat() throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public void testCat() throws IOException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("a.txt");
|
||||
@@ -75,32 +81,58 @@ public class GitCatCommandTest extends AbstractGitCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCat() throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public void testSimpleCat() throws IOException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("b.txt");
|
||||
assertEquals("b", execute(request));
|
||||
}
|
||||
|
||||
@Test(expected = PathNotFoundException.class)
|
||||
public void testUnknownFile() throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
@Test
|
||||
public void testUnknownFile() throws IOException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("unknown");
|
||||
execute(request);
|
||||
}
|
||||
|
||||
@Test(expected = RevisionNotFoundException.class)
|
||||
public void testUnknownRevision() throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
expectedException.expect(new BaseMatcher<Object>() {
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("expected NotFoundException for path");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object item) {
|
||||
return "Path".equals(((NotFoundException)item).getContext().get(0).getType());
|
||||
}
|
||||
});
|
||||
|
||||
request.setRevision("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
request.setPath("a.txt");
|
||||
execute(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleStream() throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public void testUnknownRevision() throws IOException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setRevision("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
request.setPath("a.txt");
|
||||
|
||||
expectedException.expect(new BaseMatcher<Object>() {
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("expected NotFoundException for revision");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object item) {
|
||||
return "Revision".equals(((NotFoundException)item).getContext().get(0).getType());
|
||||
}
|
||||
});
|
||||
|
||||
execute(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleStream() throws IOException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
request.setPath("b.txt");
|
||||
|
||||
@@ -113,7 +145,7 @@ public class GitCatCommandTest extends AbstractGitCommandTestBase {
|
||||
catResultStream.close();
|
||||
}
|
||||
|
||||
private String execute(CatCommandRequest request) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
private String execute(CatCommandRequest request) throws IOException {
|
||||
String content = null;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ public class AbstractHgHandler
|
||||
} catch (JAXBException ex) {
|
||||
logger.error("could not parse result", ex);
|
||||
|
||||
throw new InternalRepositoryException("could not parse result", ex);
|
||||
throw new InternalRepositoryException(repository, "could not parse result", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ package sonia.scm.repository.spi;
|
||||
import com.aragost.javahg.commands.ExecutionException;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Closeables;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.web.HgUtil;
|
||||
@@ -46,6 +49,8 @@ import java.io.OutputStream;
|
||||
|
||||
public class HgCatCommand extends AbstractCommand implements CatCommand {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(HgCatCommand.class);
|
||||
|
||||
HgCatCommand(HgCommandContext context, Repository repository) {
|
||||
super(context, repository);
|
||||
}
|
||||
@@ -70,7 +75,8 @@ public class HgCatCommand extends AbstractCommand implements CatCommand {
|
||||
try {
|
||||
return cmd.execute(request.getPath());
|
||||
} catch (ExecutionException e) {
|
||||
throw new InternalRepositoryException(e);
|
||||
log.error("could not execute cat command", e);
|
||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity(getRepository()), "could not execute cat command", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class HgIncomingCommand extends AbstractCommand
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute incoming command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute incoming command", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public class HgOutgoingCommand extends AbstractCommand
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute outgoing command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute outgoing command", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public class HgPullCommand extends AbstractHgPushOrPullCommand
|
||||
}
|
||||
catch (ExecutionException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute push command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute push command", ex);
|
||||
}
|
||||
|
||||
return new PullResponse(result.size());
|
||||
|
||||
@@ -97,7 +97,7 @@ public class HgPushCommand extends AbstractHgPushOrPullCommand
|
||||
}
|
||||
catch (ExecutionException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute push command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute push command", ex);
|
||||
}
|
||||
|
||||
return new PushResponse(result.size());
|
||||
|
||||
@@ -44,11 +44,11 @@ import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.HgContext;
|
||||
import sonia.scm.repository.HgHookManager;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RepositoryUtil;
|
||||
import sonia.scm.repository.api.HgHookMessage;
|
||||
import sonia.scm.repository.api.HgHookMessage.Severity;
|
||||
@@ -275,17 +275,11 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
printMessages(response, context);
|
||||
}
|
||||
catch (RepositoryNotFoundException ex)
|
||||
catch (NotFoundException ex)
|
||||
{
|
||||
if (logger.isErrorEnabled())
|
||||
{
|
||||
logger.error("could not find repository with id {}", id);
|
||||
logger.error(ex.getMessage());
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("repository not found", ex);
|
||||
}
|
||||
}
|
||||
logger.trace("repository not found", ex);
|
||||
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import org.junit.Test;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -151,7 +150,7 @@ public class HgLogCommandTest extends AbstractHgCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommit() throws IOException, RevisionNotFoundException {
|
||||
public void testGetCommit() throws IOException {
|
||||
HgLogCommand command = createComamnd();
|
||||
String revision = "a9bacaf1b7fa0cebfca71fed4e59ed69a6319427";
|
||||
Changeset c =
|
||||
|
||||
@@ -56,6 +56,8 @@ import sonia.scm.util.Util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -173,7 +175,8 @@ public class SvnRepositoryHandler
|
||||
}
|
||||
catch (SVNException ex)
|
||||
{
|
||||
throw new InternalRepositoryException(ex);
|
||||
logger.error("could not create svn repository", ex);
|
||||
throw new InternalRepositoryException(entity(repository), "could not create repository", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -59,6 +59,9 @@ import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -102,7 +105,7 @@ public final class SvnUtil
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
public static long parseRevision(String v) throws RevisionNotFoundException {
|
||||
public static long parseRevision(String v, Repository repository) {
|
||||
long result = -1l;
|
||||
|
||||
if (!Strings.isNullOrEmpty(v))
|
||||
@@ -113,7 +116,7 @@ public final class SvnUtil
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
throw new RevisionNotFoundException(v);
|
||||
throw notFound(entity("Revision", v).in(repository));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +342,7 @@ public final class SvnUtil
|
||||
}
|
||||
}
|
||||
|
||||
public static long getRevisionNumber(String revision) throws RevisionNotFoundException {
|
||||
public static long getRevisionNumber(String revision, Repository repository) {
|
||||
// REVIEW Bei SVN wird ohne Revision die -1 genommen, was zu einem Fehler führt
|
||||
long revisionNumber = -1;
|
||||
|
||||
@@ -351,7 +354,7 @@ public final class SvnUtil
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
throw new RevisionNotFoundException(revision);
|
||||
throw notFound(entity("Revision", revision).in(repository));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public class SvnBlameCommand extends AbstractSvnCommand implements BlameCommand
|
||||
}
|
||||
catch (SVNException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not create blame result", ex);
|
||||
throw new InternalRepositoryException(repository, "could not create blame result", ex);
|
||||
}
|
||||
|
||||
return new BlameResult(blameLines.size(), blameLines);
|
||||
|
||||
@@ -48,7 +48,6 @@ import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import sonia.scm.repository.BrowserResult;
|
||||
import sonia.scm.repository.FileObject;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.SubRepository;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
import sonia.scm.util.Util;
|
||||
@@ -79,9 +78,9 @@ public class SvnBrowseCommand extends AbstractSvnCommand
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public BrowserResult getBrowserResult(BrowseCommandRequest request) throws RevisionNotFoundException {
|
||||
public BrowserResult getBrowserResult(BrowseCommandRequest request) {
|
||||
String path = Strings.nullToEmpty(request.getPath());
|
||||
long revisionNumber = SvnUtil.getRevisionNumber(request.getRevision());
|
||||
long revisionNumber = SvnUtil.getRevisionNumber(request.getRevision(), repository);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("browser repository {} in path \"{}\" at revision {}", repository.getName(), path, revisionNumber);
|
||||
|
||||
@@ -44,9 +44,7 @@ import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
||||
import org.tmatesoft.svn.core.wc.admin.SVNLookClient;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -54,6 +52,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -79,7 +80,7 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void getCatResult(CatCommandRequest request, OutputStream output) throws RevisionNotFoundException, PathNotFoundException {
|
||||
public void getCatResult(CatCommandRequest request, OutputStream output) {
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("try to get content for {}", request);
|
||||
@@ -96,14 +97,14 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand
|
||||
else
|
||||
{
|
||||
|
||||
long revisionNumber = SvnUtil.getRevisionNumber(revision);
|
||||
long revisionNumber = SvnUtil.getRevisionNumber(revision, repository);
|
||||
|
||||
getCatFromRevision(request, output, revisionNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getCatResultStream(CatCommandRequest request) throws RevisionNotFoundException, PathNotFoundException {
|
||||
public InputStream getCatResultStream(CatCommandRequest request) {
|
||||
// There seems to be no method creating an input stream as a result, so
|
||||
// we have no other possibility then to copy the content into a buffer and
|
||||
// stream it from there.
|
||||
@@ -112,7 +113,7 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand
|
||||
return new ByteArrayInputStream(output.toByteArray());
|
||||
}
|
||||
|
||||
private void getCatFromRevision(CatCommandRequest request, OutputStream output, long revision) throws PathNotFoundException, RevisionNotFoundException {
|
||||
private void getCatFromRevision(CatCommandRequest request, OutputStream output, long revision) {
|
||||
logger.debug("try to read content from revision {} and path {}", revision,
|
||||
request.getPath());
|
||||
|
||||
@@ -129,14 +130,14 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSvnException(CatCommandRequest request, SVNException ex) throws PathNotFoundException, RevisionNotFoundException {
|
||||
private void handleSvnException(CatCommandRequest request, SVNException ex) {
|
||||
int svnErrorCode = ex.getErrorMessage().getErrorCode().getCode();
|
||||
if (SVNErrorCode.FS_NOT_FOUND.getCode() == svnErrorCode) {
|
||||
throw new PathNotFoundException(request.getPath());
|
||||
throw notFound(entity("Path", request.getPath()).in("Revision", request.getRevision()).in(repository));
|
||||
} else if (SVNErrorCode.FS_NO_SUCH_REVISION.getCode() == svnErrorCode) {
|
||||
throw new RevisionNotFoundException(request.getRevision());
|
||||
throw notFound(entity("Revision", request.getRevision()).in(repository));
|
||||
} else {
|
||||
throw new InternalRepositoryException("could not get content from revision", ex);
|
||||
throw new InternalRepositoryException(repository, "could not get content from revision", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +157,7 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand
|
||||
}
|
||||
catch (SVNException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not get content from transaction", ex);
|
||||
throw new InternalRepositoryException(repository, "could not get content from transaction", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand {
|
||||
SVNDiffClient diffClient = clientManager.getDiffClient();
|
||||
diffClient.setDiffGenerator(new SvnNewDiffGenerator(new SCMSvnDiffGenerator()));
|
||||
|
||||
long currentRev = SvnUtil.getRevisionNumber(request.getRevision());
|
||||
long currentRev = SvnUtil.getRevisionNumber(request.getRevision(), repository);
|
||||
|
||||
diffClient.setGitDiffFormat(request.getFormat() == DiffFormat.GIT);
|
||||
|
||||
@@ -94,7 +94,7 @@ public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand {
|
||||
SVNRevision.create(currentRev - 1), SVNRevision.create(currentRev),
|
||||
SVNDepth.INFINITY, false, output);
|
||||
} catch (SVNException ex) {
|
||||
throw new InternalRepositoryException("could not create diff", ex);
|
||||
throw new InternalRepositoryException(repository, "could not create diff", ex);
|
||||
} finally {
|
||||
SvnUtil.dispose(clientManager);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
@@ -76,7 +75,7 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Changeset getChangeset(String revision) throws RevisionNotFoundException {
|
||||
public Changeset getChangeset(String revision) {
|
||||
Changeset changeset = null;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
@@ -86,7 +85,7 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
|
||||
try
|
||||
{
|
||||
long revisioNumber = parseRevision(revision);
|
||||
long revisioNumber = parseRevision(revision, repository);
|
||||
SVNRepository repo = open();
|
||||
Collection<SVNLogEntry> entries = repo.log(null, null, revisioNumber,
|
||||
revisioNumber, true, true);
|
||||
@@ -98,7 +97,7 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
}
|
||||
catch (SVNException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not open repository", ex);
|
||||
throw new InternalRepositoryException(repository, "could not open repository", ex);
|
||||
}
|
||||
|
||||
return changeset;
|
||||
@@ -106,7 +105,7 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ChangesetPagingResult getChangesets(LogCommandRequest request) throws RevisionNotFoundException {
|
||||
public ChangesetPagingResult getChangesets(LogCommandRequest request) {
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("fetch changesets for {}", request);
|
||||
@@ -115,8 +114,8 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
ChangesetPagingResult changesets = null;
|
||||
int start = request.getPagingStart();
|
||||
int limit = request.getPagingLimit();
|
||||
long startRevision = parseRevision(request.getStartChangeset());
|
||||
long endRevision = parseRevision(request.getEndChangeset());
|
||||
long startRevision = parseRevision(request.getStartChangeset(), repository);
|
||||
long endRevision = parseRevision(request.getEndChangeset(), repository);
|
||||
String[] pathArray = null;
|
||||
|
||||
if (!Strings.isNullOrEmpty(request.getPath()))
|
||||
@@ -140,7 +139,7 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand
|
||||
}
|
||||
catch (SVNException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not open repository", ex);
|
||||
throw new InternalRepositoryException(repository, "could not open repository", ex);
|
||||
}
|
||||
|
||||
return changesets;
|
||||
|
||||
@@ -7,11 +7,9 @@ import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
@Slf4j
|
||||
@@ -24,11 +22,11 @@ public class SvnModificationsCommand extends AbstractSvnCommand implements Modif
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Modifications getModifications(String revision) throws IOException, RevisionNotFoundException {
|
||||
public Modifications getModifications(String revision) {
|
||||
Modifications modifications = null;
|
||||
log.debug("get modifications {}", revision);
|
||||
try {
|
||||
long revisionNumber = SvnUtil.parseRevision(revision);
|
||||
long revisionNumber = SvnUtil.parseRevision(revision, repository);
|
||||
SVNRepository repo = open();
|
||||
Collection<SVNLogEntry> entries = repo.log(null, null, revisionNumber,
|
||||
revisionNumber, true, true);
|
||||
@@ -36,13 +34,13 @@ public class SvnModificationsCommand extends AbstractSvnCommand implements Modif
|
||||
modifications = SvnUtil.createModifications(entries.iterator().next(), revision);
|
||||
}
|
||||
} catch (SVNException ex) {
|
||||
throw new InternalRepositoryException("could not open repository", ex);
|
||||
throw new InternalRepositoryException(repository, "could not open repository", ex);
|
||||
}
|
||||
return modifications;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifications getModifications(ModificationsCommandRequest request) throws IOException, RevisionNotFoundException {
|
||||
public Modifications getModifications(ModificationsCommandRequest request) {
|
||||
return getModifications(request.getRevision());
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ package sonia.scm.repository.spi;
|
||||
import org.junit.Test;
|
||||
import sonia.scm.repository.BrowserResult;
|
||||
import sonia.scm.repository.FileObject;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
@@ -55,7 +54,7 @@ public class SvnBrowseCommandTest extends AbstractSvnCommandTestBase
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testBrowseWithFilePath() throws RevisionNotFoundException {
|
||||
public void testBrowseWithFilePath() {
|
||||
BrowseCommandRequest request = new BrowseCommandRequest();
|
||||
request.setPath("a.txt");
|
||||
FileObject file = createCommand().getBrowserResult(request).getFile();
|
||||
@@ -65,7 +64,7 @@ public class SvnBrowseCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrowse() throws RevisionNotFoundException {
|
||||
public void testBrowse() {
|
||||
Collection<FileObject> foList = getRootFromTip(new BrowseCommandRequest());
|
||||
|
||||
FileObject a = getFileObject(foList, "a.txt");
|
||||
@@ -89,7 +88,7 @@ public class SvnBrowseCommandTest extends AbstractSvnCommandTestBase
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testBrowseSubDirectory() throws RevisionNotFoundException {
|
||||
public void testBrowseSubDirectory() {
|
||||
BrowseCommandRequest request = new BrowseCommandRequest();
|
||||
|
||||
request.setPath("c");
|
||||
@@ -136,7 +135,7 @@ public class SvnBrowseCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableLastCommit() throws RevisionNotFoundException {
|
||||
public void testDisableLastCommit() {
|
||||
BrowseCommandRequest request = new BrowseCommandRequest();
|
||||
|
||||
request.setDisableLastCommit(true);
|
||||
@@ -150,7 +149,7 @@ public class SvnBrowseCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecursive() throws RevisionNotFoundException {
|
||||
public void testRecursive() {
|
||||
BrowseCommandRequest request = new BrowseCommandRequest();
|
||||
request.setRecursive(true);
|
||||
BrowserResult result = createCommand().getBrowserResult(request);
|
||||
@@ -199,7 +198,7 @@ public class SvnBrowseCommandTest extends AbstractSvnCommandTestBase
|
||||
.orElseThrow(() -> new AssertionError("file " + name + " not found"));
|
||||
}
|
||||
|
||||
private Collection<FileObject> getRootFromTip(BrowseCommandRequest request) throws RevisionNotFoundException {
|
||||
private Collection<FileObject> getRootFromTip(BrowseCommandRequest request) {
|
||||
BrowserResult result = createCommand().getBrowserResult(request);
|
||||
|
||||
assertNotNull(result);
|
||||
|
||||
@@ -32,9 +32,12 @@
|
||||
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import sonia.scm.NotFoundException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -46,8 +49,11 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class SvnCatCommandTest extends AbstractSvnCommandTestBase {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testCat() throws PathNotFoundException, RevisionNotFoundException {
|
||||
public void testCat() {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("a.txt");
|
||||
@@ -56,35 +62,59 @@ public class SvnCatCommandTest extends AbstractSvnCommandTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCat() throws PathNotFoundException, RevisionNotFoundException {
|
||||
public void testSimpleCat() {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("c/d.txt");
|
||||
assertEquals("d", execute(request));
|
||||
}
|
||||
|
||||
@Test(expected = PathNotFoundException.class)
|
||||
public void testUnknownFile() throws PathNotFoundException, RevisionNotFoundException {
|
||||
@Test
|
||||
public void testUnknownFile() {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("unknown");
|
||||
request.setRevision("1");
|
||||
|
||||
execute(request);
|
||||
}
|
||||
expectedException.expect(new BaseMatcher<Object>() {
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("expected NotFoundException for path");
|
||||
}
|
||||
|
||||
@Test(expected = RevisionNotFoundException.class)
|
||||
public void testUnknownRevision() throws PathNotFoundException, RevisionNotFoundException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("a.txt");
|
||||
request.setRevision("42");
|
||||
@Override
|
||||
public boolean matches(Object item) {
|
||||
return "Path".equals(((NotFoundException)item).getContext().get(0).getType());
|
||||
}
|
||||
});
|
||||
|
||||
execute(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleStream() throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
public void testUnknownRevision() {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
|
||||
request.setPath("a.txt");
|
||||
request.setRevision("42");
|
||||
|
||||
expectedException.expect(new BaseMatcher<Object>() {
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("expected NotFoundException for revision");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object item) {
|
||||
return "Revision".equals(((NotFoundException)item).getContext().get(0).getType());
|
||||
}
|
||||
});
|
||||
|
||||
execute(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleStream() throws IOException {
|
||||
CatCommandRequest request = new CatCommandRequest();
|
||||
request.setPath("a.txt");
|
||||
request.setRevision("1");
|
||||
@@ -98,7 +128,7 @@ public class SvnCatCommandTest extends AbstractSvnCommandTestBase {
|
||||
catResultStream.close();
|
||||
}
|
||||
|
||||
private String execute(CatCommandRequest request) throws PathNotFoundException, RevisionNotFoundException {
|
||||
private String execute(CatCommandRequest request) {
|
||||
String content = null;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.junit.Test;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -57,7 +56,7 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testGetAll() throws RevisionNotFoundException {
|
||||
public void testGetAll() {
|
||||
ChangesetPagingResult result =
|
||||
createCommand().getChangesets(new LogCommandRequest());
|
||||
|
||||
@@ -67,7 +66,7 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllByPath() throws RevisionNotFoundException {
|
||||
public void testGetAllByPath() {
|
||||
LogCommandRequest request = new LogCommandRequest();
|
||||
|
||||
request.setPath("a.txt");
|
||||
@@ -83,7 +82,7 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllWithLimit() throws RevisionNotFoundException {
|
||||
public void testGetAllWithLimit() {
|
||||
LogCommandRequest request = new LogCommandRequest();
|
||||
|
||||
request.setPagingLimit(2);
|
||||
@@ -106,7 +105,7 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllWithPaging() throws RevisionNotFoundException {
|
||||
public void testGetAllWithPaging() {
|
||||
LogCommandRequest request = new LogCommandRequest();
|
||||
|
||||
request.setPagingStart(1);
|
||||
@@ -130,7 +129,7 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommit() throws RevisionNotFoundException, IOException {
|
||||
public void testGetCommit() {
|
||||
Changeset c = createCommand().getChangeset("3");
|
||||
|
||||
assertNotNull(c);
|
||||
@@ -151,7 +150,7 @@ public class SvnLogCommandTest extends AbstractSvnCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRange() throws RevisionNotFoundException {
|
||||
public void testGetRange() {
|
||||
LogCommandRequest request = new LogCommandRequest();
|
||||
|
||||
request.setStartChangeset("2");
|
||||
|
||||
@@ -71,10 +71,10 @@ public class DummyRepositoryHandler
|
||||
|
||||
|
||||
@Override
|
||||
protected void create(Repository repository, File directory) throws AlreadyExistsException {
|
||||
protected void create(Repository repository, File directory) {
|
||||
String key = repository.getNamespace() + "/" + repository.getName();
|
||||
if (existingRepoNames.contains(key)) {
|
||||
throw new AlreadyExistsException();
|
||||
throw new AlreadyExistsException(repository);
|
||||
} else {
|
||||
existingRepoNames.add(key);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ package sonia.scm.repository;
|
||||
|
||||
import org.junit.Test;
|
||||
import sonia.scm.AbstractTestBase;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.store.ConfigurationStoreFactory;
|
||||
import sonia.scm.store.InMemoryConfigurationStoreFactory;
|
||||
import sonia.scm.util.IOUtil;
|
||||
@@ -61,12 +60,12 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
ConfigurationStoreFactory factory, File directory);
|
||||
|
||||
@Test
|
||||
public void testCreate() throws AlreadyExistsException {
|
||||
public void testCreate() {
|
||||
createRepository();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateResourcePath() throws AlreadyExistsException {
|
||||
public void testCreateResourcePath() {
|
||||
Repository repository = createRepository();
|
||||
String path = handler.createResourcePath(repository);
|
||||
|
||||
@@ -76,7 +75,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() throws Exception {
|
||||
public void testDelete() {
|
||||
Repository repository = createRepository();
|
||||
|
||||
handler.delete(repository);
|
||||
@@ -101,7 +100,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
private Repository createRepository() throws AlreadyExistsException {
|
||||
private Repository createRepository() {
|
||||
Repository repository = RepositoryTestData.createHeartOfGold();
|
||||
|
||||
handler.create(repository);
|
||||
|
||||
@@ -39,12 +39,10 @@ import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.junit.Test;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.ConcurrentModificationException;
|
||||
import sonia.scm.Manager;
|
||||
import sonia.scm.ManagerTestBase;
|
||||
import sonia.scm.NotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -63,7 +61,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
public static final int THREAD_COUNT = 10;
|
||||
|
||||
@Test
|
||||
public void testCreate() throws AlreadyExistsException {
|
||||
public void testCreate() {
|
||||
User zaphod = UserTestData.createZaphod();
|
||||
|
||||
manager.create(zaphod);
|
||||
@@ -75,7 +73,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
}
|
||||
|
||||
@Test(expected = AlreadyExistsException.class)
|
||||
public void testCreateExisting() throws AlreadyExistsException {
|
||||
public void testCreateExisting() {
|
||||
User zaphod = UserTestData.createZaphod();
|
||||
|
||||
manager.create(zaphod);
|
||||
@@ -87,7 +85,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() throws Exception {
|
||||
public void testDelete() {
|
||||
User zaphod = UserTestData.createZaphod();
|
||||
|
||||
manager.create(zaphod);
|
||||
@@ -97,12 +95,12 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
}
|
||||
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void testDeleteNotFound() throws Exception {
|
||||
public void testDeleteNotFound() {
|
||||
manager.delete(UserTestData.createDent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGet() throws AlreadyExistsException {
|
||||
public void testGet() {
|
||||
User zaphod = UserTestData.createZaphod();
|
||||
|
||||
manager.create(zaphod);
|
||||
@@ -116,7 +114,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAll() throws AlreadyExistsException {
|
||||
public void testGetAll() {
|
||||
User zaphod = UserTestData.createZaphod();
|
||||
|
||||
manager.create(zaphod);
|
||||
@@ -181,7 +179,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModify() throws AlreadyExistsException, NotFoundException, ConcurrentModificationException {
|
||||
public void testModify() {
|
||||
User zaphod = UserTestData.createZaphod();
|
||||
|
||||
manager.create(zaphod);
|
||||
@@ -238,7 +236,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefresh() throws AlreadyExistsException, NotFoundException {
|
||||
public void testRefresh() {
|
||||
User zaphod = UserTestData.createZaphod();
|
||||
|
||||
manager.create(zaphod);
|
||||
@@ -289,7 +287,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
finished = true;
|
||||
}
|
||||
|
||||
private User createUser() throws AlreadyExistsException {
|
||||
private User createUser() {
|
||||
String id = UUID.randomUUID().toString();
|
||||
User user = new User(id, id.concat(" displayName"),
|
||||
id.concat("@mail.com"));
|
||||
@@ -299,7 +297,7 @@ public abstract class UserManagerTestBase extends ManagerTestBase<User> {
|
||||
return user;
|
||||
}
|
||||
|
||||
private void modifyAndDeleteUser(User user) throws IOException, NotFoundException, ConcurrentModificationException {
|
||||
private void modifyAndDeleteUser(User user) {
|
||||
String name = user.getName();
|
||||
String nd = name.concat(" new displayname");
|
||||
|
||||
|
||||
@@ -30,19 +30,19 @@ public class ManagerDaoAdapter<T extends ModelObject> {
|
||||
|
||||
afterUpdate.handle(notModified);
|
||||
} else {
|
||||
throw new NotFoundException();
|
||||
throw new NotFoundException(object.getClass(), object.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public T create(T newObject, Supplier<PermissionCheck> permissionCheck, AroundHandler<T> beforeCreate, AroundHandler<T> afterCreate) throws AlreadyExistsException {
|
||||
public T create(T newObject, Supplier<PermissionCheck> permissionCheck, AroundHandler<T> beforeCreate, AroundHandler<T> afterCreate) {
|
||||
return create(newObject, permissionCheck, beforeCreate, afterCreate, dao::contains);
|
||||
}
|
||||
|
||||
public T create(T newObject, Supplier<PermissionCheck> permissionCheck, AroundHandler<T> beforeCreate, AroundHandler<T> afterCreate, Predicate<T> existsCheck) throws AlreadyExistsException {
|
||||
public T create(T newObject, Supplier<PermissionCheck> permissionCheck, AroundHandler<T> beforeCreate, AroundHandler<T> afterCreate, Predicate<T> existsCheck) {
|
||||
permissionCheck.get().check();
|
||||
AssertUtil.assertIsValid(newObject);
|
||||
if (existsCheck.test(newObject)) {
|
||||
throw new AlreadyExistsException();
|
||||
throw new AlreadyExistsException(newObject);
|
||||
}
|
||||
newObject.setCreationDate(System.currentTimeMillis());
|
||||
beforeCreate.handle(newObject);
|
||||
@@ -58,7 +58,7 @@ public class ManagerDaoAdapter<T extends ModelObject> {
|
||||
dao.delete(toDelete);
|
||||
afterDelete.handle(toDelete);
|
||||
} else {
|
||||
throw new NotFoundException();
|
||||
throw new NotFoundException(toDelete.getClass(), toDelete.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package sonia.scm.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import sonia.scm.api.v2.resources.ErrorDto;
|
||||
import sonia.scm.api.v2.resources.ExceptionWithContextToErrorDtoMapper;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import java.util.Collections;
|
||||
|
||||
@Provider
|
||||
public class FallbackExceptionMapper implements ExceptionMapper<Exception> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FallbackExceptionMapper.class);
|
||||
|
||||
private static final String ERROR_CODE = "CmR8GCJb31";
|
||||
|
||||
private final ExceptionWithContextToErrorDtoMapper mapper;
|
||||
|
||||
@Inject
|
||||
public FallbackExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response toResponse(Exception exception) {
|
||||
logger.debug("map {} to status code 500", exception);
|
||||
ErrorDto errorDto = new ErrorDto();
|
||||
errorDto.setMessage("internal server error");
|
||||
errorDto.setContext(Collections.emptyList());
|
||||
errorDto.setErrorCode(ERROR_CODE);
|
||||
errorDto.setTransactionId(MDC.get("transaction_id"));
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(errorDto)
|
||||
.type(VndMediaType.ERROR_TYPE)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,16 @@
|
||||
package sonia.scm.api.rest;
|
||||
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.api.v2.resources.ExceptionWithContextToErrorDtoMapper;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
@Provider
|
||||
public class AlreadyExistsExceptionMapper implements ExceptionMapper<AlreadyExistsException> {
|
||||
@Override
|
||||
public Response toResponse(AlreadyExistsException exception) {
|
||||
return Response.status(Status.CONFLICT)
|
||||
.entity(exception.getMessage())
|
||||
.build();
|
||||
public class AlreadyExistsExceptionMapper extends ContextualExceptionMapper<AlreadyExistsException> {
|
||||
@Inject
|
||||
public AlreadyExistsExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
super(AlreadyExistsException.class, Status.CONFLICT, mapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package sonia.scm.api.rest;
|
||||
|
||||
import sonia.scm.ConcurrentModificationException;
|
||||
import sonia.scm.api.v2.resources.ExceptionWithContextToErrorDtoMapper;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
@Provider
|
||||
public class ConcurrentModificationExceptionMapper implements ExceptionMapper<ConcurrentModificationException> {
|
||||
@Override
|
||||
public Response toResponse(ConcurrentModificationException exception) {
|
||||
return Response.status(Response.Status.CONFLICT).build();
|
||||
public class ConcurrentModificationExceptionMapper extends ContextualExceptionMapper<ConcurrentModificationException> {
|
||||
@Inject
|
||||
public ConcurrentModificationExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
super(ConcurrentModificationException.class, Response.Status.CONFLICT, mapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package sonia.scm.api.rest;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ExceptionWithContext;
|
||||
import sonia.scm.api.v2.resources.ExceptionWithContextToErrorDtoMapper;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
|
||||
public class ContextualExceptionMapper<E extends ExceptionWithContext> implements ExceptionMapper<E> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContextualExceptionMapper.class);
|
||||
|
||||
private final ExceptionWithContextToErrorDtoMapper mapper;
|
||||
|
||||
private final Response.Status status;
|
||||
private final Class<E> type;
|
||||
|
||||
public ContextualExceptionMapper(Class<E> type, Response.Status status, ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
this.mapper = mapper;
|
||||
this.type = type;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response toResponse(E exception) {
|
||||
logger.debug("map {} to status code {}", type.getSimpleName(), status.getStatusCode(), exception);
|
||||
return Response.status(status)
|
||||
.entity(mapper.map(exception))
|
||||
.type(VndMediaType.ERROR_TYPE)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ package sonia.scm.api.rest.resources;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.CatCommandBuilder;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.util.IOUtil;
|
||||
@@ -34,18 +32,6 @@ public class BrowserStreamingOutput implements StreamingOutput {
|
||||
public void write(OutputStream output) throws IOException {
|
||||
try {
|
||||
builder.retriveContent(output, path);
|
||||
} catch (PathNotFoundException ex) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("could not find path {}", ex.getPath());
|
||||
}
|
||||
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
} catch (RevisionNotFoundException ex) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("could not find revision {}", ex.getRevision());
|
||||
}
|
||||
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
} finally {
|
||||
IOUtil.close(repositoryService);
|
||||
}
|
||||
|
||||
@@ -44,8 +44,6 @@ import org.apache.shiro.authc.credential.PasswordService;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ConcurrentModificationException;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.api.rest.RestActionResult;
|
||||
import sonia.scm.security.Role;
|
||||
import sonia.scm.security.ScmSecurityException;
|
||||
|
||||
@@ -37,7 +37,6 @@ package sonia.scm.api.rest.resources;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.DiffCommandBuilder;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.util.IOUtil;
|
||||
@@ -95,22 +94,6 @@ public class DiffStreamingOutput implements StreamingOutput
|
||||
{
|
||||
builder.retrieveContent(output);
|
||||
}
|
||||
catch (RevisionNotFoundException ex)
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("could not find revision {}", ex.getRevision());
|
||||
}
|
||||
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
}
|
||||
// catch (RepositoryException ex)
|
||||
// {
|
||||
// logger.error("could not write content to page", ex);
|
||||
//
|
||||
// throw new WebApplicationException(ex,
|
||||
// Response.Status.INTERNAL_SERVER_ERROR);
|
||||
// }
|
||||
finally
|
||||
{
|
||||
IOUtil.close(repositoryService);
|
||||
|
||||
@@ -45,11 +45,11 @@ import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.NotSupportedFeatuerException;
|
||||
import sonia.scm.NotSupportedFeatureException;
|
||||
import sonia.scm.Type;
|
||||
import sonia.scm.api.rest.RestActionUploadResult;
|
||||
import sonia.scm.api.v2.resources.RepositoryResource;
|
||||
import sonia.scm.repository.*;
|
||||
import sonia.scm.repository.api.Command;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
@@ -394,7 +394,7 @@ public class RepositoryImportResource
|
||||
|
||||
response = Response.ok(result).build();
|
||||
}
|
||||
catch (NotSupportedFeatuerException ex)
|
||||
catch (NotSupportedFeatureException ex)
|
||||
{
|
||||
logger
|
||||
.warn(
|
||||
@@ -515,13 +515,6 @@ public class RepositoryImportResource
|
||||
// repository = new Repository(null, type, name);
|
||||
manager.create(repository);
|
||||
}
|
||||
catch (AlreadyExistsException ex)
|
||||
{
|
||||
logger.warn("a {} repository with the name {} already exists", type,
|
||||
name);
|
||||
|
||||
throw new WebApplicationException(Response.Status.CONFLICT);
|
||||
}
|
||||
catch (InternalRepositoryException ex)
|
||||
{
|
||||
handleGenericCreationFailure(ex, type, name);
|
||||
@@ -616,7 +609,7 @@ public class RepositoryImportResource
|
||||
types.add(t);
|
||||
}
|
||||
}
|
||||
catch (NotSupportedFeatuerException ex)
|
||||
catch (NotSupportedFeatureException ex)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
@@ -718,7 +711,7 @@ public class RepositoryImportResource
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotSupportedFeatuerException ex)
|
||||
catch (NotSupportedFeatureException ex)
|
||||
{
|
||||
throw new WebApplicationException(ex, Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,12 +28,14 @@
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.api.v2.resources;
|
||||
package sonia.scm.api.v2;
|
||||
|
||||
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.api.rest.StatusExceptionMapper;
|
||||
import sonia.scm.api.rest.ContextualExceptionMapper;
|
||||
import sonia.scm.api.v2.resources.ExceptionWithContextToErrorDtoMapper;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
@@ -41,9 +43,9 @@ import javax.ws.rs.ext.Provider;
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Provider
|
||||
public class NotFoundExceptionMapper extends StatusExceptionMapper<NotFoundException> {
|
||||
|
||||
public NotFoundExceptionMapper() {
|
||||
super(NotFoundException.class, Response.Status.NOT_FOUND);
|
||||
public class NotFoundExceptionMapper extends ContextualExceptionMapper<NotFoundException> {
|
||||
@Inject
|
||||
public NotFoundExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
super(NotFoundException.class, Response.Status.NOT_FOUND, mapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package sonia.scm.api.v2;
|
||||
|
||||
import sonia.scm.NotSupportedFeatureException;
|
||||
import sonia.scm.api.rest.ContextualExceptionMapper;
|
||||
import sonia.scm.api.v2.resources.ExceptionWithContextToErrorDtoMapper;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
@Provider
|
||||
public class NotSupportedFeatureExceptionMapper extends ContextualExceptionMapper<NotSupportedFeatureException> {
|
||||
@Inject
|
||||
public NotSupportedFeatureExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
super(NotSupportedFeatureException.class, Response.Status.BAD_REQUEST, mapper);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,30 @@
|
||||
package sonia.scm.api.v2;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.jboss.resteasy.api.validation.ResteasyViolationException;
|
||||
import sonia.scm.api.v2.resources.ViolationExceptionToErrorDtoMapper;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Provider
|
||||
public class ValidationExceptionMapper implements ExceptionMapper<ResteasyViolationException> {
|
||||
|
||||
private final ViolationExceptionToErrorDtoMapper mapper;
|
||||
|
||||
@Inject
|
||||
public ValidationExceptionMapper(ViolationExceptionToErrorDtoMapper mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response toResponse(ResteasyViolationException exception) {
|
||||
|
||||
List<ConstraintViolationBean> violations =
|
||||
exception.getConstraintViolations()
|
||||
.stream()
|
||||
.map(ConstraintViolationBean::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Response
|
||||
.status(Response.Status.BAD_REQUEST)
|
||||
.type(MediaType.APPLICATION_JSON_TYPE)
|
||||
.entity(new ValidationError(violations))
|
||||
.entity(mapper.map(exception))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class ValidationError {
|
||||
@XmlElement(name = "violation")
|
||||
@XmlElementWrapper(name = "violations")
|
||||
private List<ConstraintViolationBean> violations;
|
||||
|
||||
public ValidationError(List<ConstraintViolationBean> violations) {
|
||||
this.violations = violations;
|
||||
}
|
||||
}
|
||||
|
||||
@XmlRootElement(name = "violation")
|
||||
@Getter
|
||||
public static class ConstraintViolationBean {
|
||||
private String path;
|
||||
private String message;
|
||||
|
||||
public ConstraintViolationBean(ConstraintViolation<?> violation) {
|
||||
message = violation.getMessage();
|
||||
path = violation.getPropertyPath().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.api.CommandNotSupportedException;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
@@ -29,6 +28,9 @@ import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
public class BranchRootResource {
|
||||
|
||||
private final RepositoryServiceFactory serviceFactory;
|
||||
@@ -79,7 +81,7 @@ public class BranchRootResource {
|
||||
.build();
|
||||
} catch (CommandNotSupportedException ex) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
@@ -99,7 +101,7 @@ public class BranchRootResource {
|
||||
@PathParam("name") String name,
|
||||
@PathParam("branch") String branchName,
|
||||
@DefaultValue("0") @QueryParam("page") int page,
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception {
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
boolean branchExists = repositoryService.getBranchesCommand()
|
||||
.getBranches()
|
||||
@@ -107,7 +109,7 @@ public class BranchRootResource {
|
||||
.stream()
|
||||
.anyMatch(branch -> branchName.equals(branch.getName()));
|
||||
if (!branchExists){
|
||||
throw new NotFoundException("branch", branchName);
|
||||
throw notFound(entity(Branch.class, branchName).in(Repository.class, namespace + "/" + name));
|
||||
}
|
||||
Repository repository = repositoryService.getRepository();
|
||||
RepositoryPermissions.read(repository).check();
|
||||
@@ -195,8 +197,6 @@ public class BranchRootResource {
|
||||
return Response.ok(branchCollectionToDtoMapper.map(namespace, name, branches.getBranches())).build();
|
||||
} catch (CommandNotSupportedException ex) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.api.rest.ContextualExceptionMapper;
|
||||
import sonia.scm.user.ChangePasswordNotAllowedException;
|
||||
import sonia.scm.user.InvalidPasswordException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
@Provider
|
||||
public class ChangePasswordNotAllowedExceptionMapper implements ExceptionMapper<ChangePasswordNotAllowedException> {
|
||||
@Override
|
||||
public Response toResponse(ChangePasswordNotAllowedException exception) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(exception.getMessage())
|
||||
.build();
|
||||
public class ChangePasswordNotAllowedExceptionMapper extends ContextualExceptionMapper<ChangePasswordNotAllowedException> {
|
||||
@Inject
|
||||
public ChangePasswordNotAllowedExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
super(ChangePasswordNotAllowedException.class, Response.Status.BAD_REQUEST, mapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,7 @@ import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
@@ -56,7 +54,7 @@ public class ChangesetRootResource {
|
||||
@Produces(VndMediaType.CHANGESET_COLLECTION)
|
||||
@TypeHint(CollectionDto.class)
|
||||
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @DefaultValue("0") @QueryParam("page") int page,
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException, RevisionNotFoundException, RepositoryNotFoundException {
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
Repository repository = repositoryService.getRepository();
|
||||
RepositoryPermissions.read(repository).check();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.Manager;
|
||||
import sonia.scm.ModelObject;
|
||||
import sonia.scm.PageResult;
|
||||
@@ -47,7 +46,7 @@ class CollectionResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||
* Creates a model object for the given dto and returns a corresponding http response.
|
||||
* This handles all corner cases, eg. no conflicts or missing privileges.
|
||||
*/
|
||||
public Response create(DTO dto, Supplier<MODEL_OBJECT> modelObjectSupplier, Function<MODEL_OBJECT, String> uriCreator) throws AlreadyExistsException {
|
||||
public Response create(DTO dto, Supplier<MODEL_OBJECT> modelObjectSupplier, Function<MODEL_OBJECT, String> uriCreator) {
|
||||
if (dto == null) {
|
||||
return Response.status(BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
@@ -6,10 +6,8 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.PathNotFoundException;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.util.IOUtil;
|
||||
@@ -64,8 +62,8 @@ public class ContentResource {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
Response.ResponseBuilder responseBuilder = Response.ok(stream);
|
||||
return createContentHeader(namespace, name, revision, path, repositoryService, responseBuilder);
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
LOG.debug("path '{}' not found in repository {}/{}", path, namespace, name, e);
|
||||
} catch (NotFoundException e) {
|
||||
LOG.debug(e.getMessage());
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
@@ -75,14 +73,8 @@ public class ContentResource {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
repositoryService.getCatCommand().setRevision(revision).retriveContent(os, path);
|
||||
os.close();
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
LOG.debug("repository {}/{} not found", path, namespace, name, e);
|
||||
throw new WebApplicationException(Status.NOT_FOUND);
|
||||
} catch (PathNotFoundException e) {
|
||||
LOG.debug("path '{}' not found in repository {}/{}", path, namespace, name, e);
|
||||
throw new WebApplicationException(Status.NOT_FOUND);
|
||||
} catch (RevisionNotFoundException e) {
|
||||
LOG.debug("revision '{}' not found in repository {}/{}", revision, namespace, name, e);
|
||||
} catch (NotFoundException e) {
|
||||
LOG.debug(e.getMessage());
|
||||
throw new WebApplicationException(Status.NOT_FOUND);
|
||||
}
|
||||
};
|
||||
@@ -111,8 +103,8 @@ public class ContentResource {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
Response.ResponseBuilder responseBuilder = Response.ok();
|
||||
return createContentHeader(namespace, name, revision, path, repositoryService, responseBuilder);
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
LOG.debug("path '{}' not found in repository {}/{}", path, namespace, name, e);
|
||||
} catch (NotFoundException e) {
|
||||
LOG.debug(e.getMessage());
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
@@ -120,12 +112,6 @@ public class ContentResource {
|
||||
private Response createContentHeader(String namespace, String name, String revision, String path, RepositoryService repositoryService, Response.ResponseBuilder responseBuilder) {
|
||||
try {
|
||||
appendContentHeader(path, getHead(revision, path, repositoryService), responseBuilder);
|
||||
} catch (PathNotFoundException e) {
|
||||
LOG.debug("path '{}' not found in repository {}/{}", path, namespace, name, e);
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
} catch (RevisionNotFoundException e) {
|
||||
LOG.debug("revision '{}' not found in repository {}/{}", revision, namespace, name, e);
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
} catch (IOException e) {
|
||||
LOG.info("error reading repository resource {} from {}/{}", path, namespace, name, e);
|
||||
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
|
||||
@@ -139,7 +125,7 @@ public class ContentResource {
|
||||
contentType.getLanguage().ifPresent(language -> responseBuilder.header("X-Programming-Language", language));
|
||||
}
|
||||
|
||||
private byte[] getHead(String revision, String path, RepositoryService repositoryService) throws IOException, PathNotFoundException, RevisionNotFoundException {
|
||||
private byte[] getHead(String revision, String path, RepositoryService repositoryService) throws IOException {
|
||||
InputStream stream = repositoryService.getCatCommand().setRevision(revision).getStream(path);
|
||||
try {
|
||||
byte[] buffer = new byte[HEAD_BUFFER_SIZE];
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.DiffFormat;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
@@ -19,7 +18,6 @@ import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.StreamingOutput;
|
||||
|
||||
@@ -62,14 +60,10 @@ public class DiffRootResource {
|
||||
DiffFormat diffFormat = DiffFormat.valueOf(format);
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
StreamingOutput responseEntry = output -> {
|
||||
try {
|
||||
repositoryService.getDiffCommand()
|
||||
.setRevision(revision)
|
||||
repositoryService.getDiffCommand()
|
||||
.setRevision(revision)
|
||||
.setFormat(diffFormat)
|
||||
.retrieveContent(output);
|
||||
} catch (RevisionNotFoundException e) {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
}
|
||||
.retrieveContent(output);
|
||||
};
|
||||
return Response.ok(responseEntry)
|
||||
.header(HEADER_CONTENT_DISPOSITION, HttpUtil.createContentDispositionAttachmentHeader(String.format("%s-%s.diff", name, revision)))
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import sonia.scm.ContextEntry;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.List;
|
||||
|
||||
@Getter @Setter
|
||||
public class ErrorDto {
|
||||
private String transactionId;
|
||||
private String errorCode;
|
||||
private List<ContextEntry> context;
|
||||
private String message;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@XmlElementWrapper(name = "violations")
|
||||
private List<ConstraintViolationDto> violations;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private String url;
|
||||
|
||||
@XmlRootElement(name = "violation")
|
||||
@Getter @Setter
|
||||
public static class ConstraintViolationDto {
|
||||
private String path;
|
||||
private String message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.slf4j.MDC;
|
||||
import sonia.scm.ExceptionWithContext;
|
||||
|
||||
@Mapper
|
||||
public abstract class ExceptionWithContextToErrorDtoMapper {
|
||||
|
||||
@Mapping(target = "errorCode", source = "code")
|
||||
@Mapping(target = "transactionId", ignore = true)
|
||||
@Mapping(target = "violations", ignore = true)
|
||||
@Mapping(target = "url", ignore = true)
|
||||
public abstract ErrorDto map(ExceptionWithContext exception);
|
||||
|
||||
@AfterMapping
|
||||
void setTransactionId(@MappingTarget ErrorDto dto) {
|
||||
dto.setTransactionId(MDC.get("transaction_id"));
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import sonia.scm.PageResult;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
@@ -26,6 +23,9 @@ import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
@Slf4j
|
||||
public class FileHistoryRootResource {
|
||||
|
||||
@@ -51,8 +51,6 @@ public class FileHistoryRootResource {
|
||||
* @param pageSize pagination
|
||||
* @return all changesets related to the given file starting with the given revision
|
||||
* @throws IOException on io error
|
||||
* @throws RevisionNotFoundException on missing revision
|
||||
* @throws RepositoryNotFoundException on missing repository
|
||||
*/
|
||||
@GET
|
||||
@Path("{revision}/{path: .*}")
|
||||
@@ -69,8 +67,9 @@ public class FileHistoryRootResource {
|
||||
@PathParam("revision") String revision,
|
||||
@PathParam("path") String path,
|
||||
@DefaultValue("0") @QueryParam("page") int page,
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException, RevisionNotFoundException, RepositoryNotFoundException {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException {
|
||||
NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name);
|
||||
try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
|
||||
log.info("Get changesets of the file {} and revision {}", path, revision);
|
||||
Repository repository = repositoryService.getRepository();
|
||||
ChangesetPagingResult changesets = new PagedLogCommandBuilder(repositoryService)
|
||||
@@ -84,9 +83,9 @@ public class FileHistoryRootResource {
|
||||
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
|
||||
return Response.ok(fileHistoryCollectionToDtoMapper.map(page, pageSize, pageResult, repository, revision, path)).build();
|
||||
} else {
|
||||
String message = String.format("for the revision %s and the file %s there is no changesets", revision, path);
|
||||
String message = String.format("for the revision %s and the file %s there are no changesets", revision, path);
|
||||
log.error(message);
|
||||
throw new InternalRepositoryException(message);
|
||||
throw notFound(entity("path", path).in("revision", revision).in(namespaceAndName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResponseHeaders;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
@@ -86,7 +86,7 @@ public class GroupCollectionResource {
|
||||
})
|
||||
@TypeHint(TypeHint.NO_CONTENT.class)
|
||||
@ResponseHeaders(@ResponseHeader(name = "Location", description = "uri to the created group"))
|
||||
public Response create(@Valid GroupDto groupDto) throws AlreadyExistsException {
|
||||
public Response create(@Valid @Named("group") GroupDto groupDto) {
|
||||
return adapter.create(groupDto,
|
||||
() -> dtoToGroupMapper.map(groupDto),
|
||||
group -> resourceLinks.group().self(group.getName()));
|
||||
|
||||
@@ -3,13 +3,12 @@ package sonia.scm.api.v2.resources;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||
import sonia.scm.ConcurrentModificationException;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
@@ -98,7 +97,7 @@ public class GroupResource {
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(TypeHint.NO_CONTENT.class)
|
||||
public Response update(@PathParam("id") String name, @Valid GroupDto groupDto) throws ConcurrentModificationException {
|
||||
public Response update(@PathParam("id") String name, @Valid @Named("group") GroupDto groupDto) {
|
||||
return adapter.update(name, existing -> dtoToGroupMapper.map(groupDto));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.ConcurrentModificationException;
|
||||
import sonia.scm.Manager;
|
||||
import sonia.scm.ModelObject;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.PageResult;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
@@ -22,6 +21,7 @@ class IdResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||
DTO extends HalRepresentation> {
|
||||
|
||||
private final Manager<MODEL_OBJECT> manager;
|
||||
private final String type;
|
||||
|
||||
private final SingleResourceManagerAdapter<MODEL_OBJECT, DTO> singleAdapter;
|
||||
private final CollectionResourceManagerAdapter<MODEL_OBJECT, DTO> collectionAdapter;
|
||||
@@ -30,13 +30,14 @@ class IdResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||
this.manager = manager;
|
||||
singleAdapter = new SingleResourceManagerAdapter<>(manager, type);
|
||||
collectionAdapter = new CollectionResourceManagerAdapter<>(manager, type);
|
||||
this.type = type.getSimpleName();
|
||||
}
|
||||
|
||||
Response get(String id, Function<MODEL_OBJECT, DTO> mapToDto) {
|
||||
return singleAdapter.get(loadBy(id), mapToDto);
|
||||
}
|
||||
|
||||
public Response update(String id, Function<MODEL_OBJECT, MODEL_OBJECT> applyChanges) throws ConcurrentModificationException {
|
||||
public Response update(String id, Function<MODEL_OBJECT, MODEL_OBJECT> applyChanges) {
|
||||
return singleAdapter.update(
|
||||
loadBy(id),
|
||||
applyChanges,
|
||||
@@ -48,7 +49,7 @@ class IdResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||
return collectionAdapter.getAll(page, pageSize, sortBy, desc, mapToDto);
|
||||
}
|
||||
|
||||
public Response create(DTO dto, Supplier<MODEL_OBJECT> modelObjectSupplier, Function<MODEL_OBJECT, String> uriCreator) throws AlreadyExistsException {
|
||||
public Response create(DTO dto, Supplier<MODEL_OBJECT> modelObjectSupplier, Function<MODEL_OBJECT, String> uriCreator) {
|
||||
return collectionAdapter.create(dto, modelObjectSupplier, uriCreator);
|
||||
}
|
||||
|
||||
@@ -56,8 +57,8 @@ class IdResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||
return singleAdapter.delete(id);
|
||||
}
|
||||
|
||||
private Supplier<Optional<MODEL_OBJECT>> loadBy(String id) {
|
||||
return () -> Optional.ofNullable(manager.get(id));
|
||||
private Supplier<MODEL_OBJECT> loadBy(String id) {
|
||||
return () -> Optional.ofNullable(manager.get(id)).orElseThrow(() -> new NotFoundException(type, id));
|
||||
}
|
||||
|
||||
private Predicate<MODEL_OBJECT> idStaysTheSame(String id) {
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.api.rest.StatusExceptionMapper;
|
||||
import sonia.scm.api.rest.ContextualExceptionMapper;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
@Provider
|
||||
public class InternalRepositoryExceptionMapper extends StatusExceptionMapper<InternalRepositoryException> {
|
||||
public class InternalRepositoryExceptionMapper extends ContextualExceptionMapper<InternalRepositoryException> {
|
||||
|
||||
public InternalRepositoryExceptionMapper() {
|
||||
super(InternalRepositoryException.class, Response.Status.INTERNAL_SERVER_ERROR);
|
||||
@Inject
|
||||
public InternalRepositoryExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
super(InternalRepositoryException.class, Response.Status.INTERNAL_SERVER_ERROR, mapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.api.rest.ContextualExceptionMapper;
|
||||
import sonia.scm.user.InvalidPasswordException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
@Provider
|
||||
public class InvalidPasswordExceptionMapper implements ExceptionMapper<InvalidPasswordException> {
|
||||
@Override
|
||||
public Response toResponse(InvalidPasswordException exception) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(exception.getMessage())
|
||||
.build();
|
||||
public class InvalidPasswordExceptionMapper extends ContextualExceptionMapper<InvalidPasswordException> {
|
||||
|
||||
@Inject
|
||||
public InvalidPasswordExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) {
|
||||
super(InvalidPasswordException.class, Response.Status.BAD_REQUEST, mapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ public class MapperModule extends AbstractModule {
|
||||
|
||||
bind(ReducedObjectModelToDtoMapper.class).to(Mappers.getMapper(ReducedObjectModelToDtoMapper.class).getClass());
|
||||
|
||||
bind(ViolationExceptionToErrorDtoMapper.class).to(Mappers.getMapper(ViolationExceptionToErrorDtoMapper.class).getClass());
|
||||
bind(ExceptionWithContextToErrorDtoMapper.class).to(Mappers.getMapper(ExceptionWithContextToErrorDtoMapper.class).getClass());
|
||||
|
||||
// no mapstruct required
|
||||
bind(UIPluginDtoMapper.class);
|
||||
bind(UIPluginDtoCollectionMapper.class);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user