diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java
index 29384ba020..e9e63d16d8 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java
@@ -38,6 +38,10 @@ package sonia.scm.api.rest.resources;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
+import com.webcohesion.enunciate.metadata.rs.ResponseCode;
+import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
+import com.webcohesion.enunciate.metadata.rs.StatusCodes;
+import com.webcohesion.enunciate.metadata.rs.TypeHint;
import sonia.scm.api.rest.Permission;
import sonia.scm.security.AssignedPermission;
@@ -114,13 +118,7 @@ public abstract class AbstractPermissionResource
//~--- methods --------------------------------------------------------------
/**
- * Adds a new permission to the user or group managed by the resource.
- *
- * Status codes:
- *
- * - 201 add successful
- * - 500 internal server error
- *
+ * Adds a new permission to the user or group managed by the resource.
*
* @param uriInfo uri informations
* @param permission permission to add
@@ -128,6 +126,13 @@ public abstract class AbstractPermissionResource
* @return web response
*/
@POST
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "creates", additionalHeaders = {
+ @ResponseHeader(name = "Location", description = "uri to new create permission")
+ }),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response add(@Context UriInfo uriInfo, Permission permission)
{
@@ -139,15 +144,7 @@ public abstract class AbstractPermissionResource
}
/**
- * Deletes a permission from the user or group managed by the resource.
- *
- * Status codes:
- *
- * - 200 delete successful
- * - 400 bad request, permission id does not belong to the user or group
- * - 404 not found, no permission with the specified id available
- * - 500 internal server error
- *
+ * Deletes a permission from the user or group managed by the resource.
*
* @param id id of the permission
*
@@ -155,6 +152,13 @@ public abstract class AbstractPermissionResource
*/
@DELETE
@Path("{id}")
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, permission id does not belong to the user or group"),
+ @ResponseCode(code = 404, condition = "not found, no permission with the specified id available"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
public Response delete(@PathParam("id") String id)
{
StoredAssignedPermission sap = getPermission(id);
@@ -165,16 +169,7 @@ public abstract class AbstractPermissionResource
}
/**
- * Updates the specified permission on the user or group managed by the
- * resource.
- *
- * Status codes:
- *
- * - 204 update successful
- * - 400 bad request, permission id does not belong to the user or group
- * - 404 not found, no permission with the specified id available
- * - 500 internal server error
- *
+ * Updates the specified permission on the user or group managed by the resource.
*
* @param id id of the permission
* @param permission updated permission
@@ -183,6 +178,13 @@ public abstract class AbstractPermissionResource
*/
@PUT
@Path("{id}")
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, permission id does not belong to the user or group"),
+ @ResponseCode(code = 404, condition = "not found, no permission with the specified id available"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response update(@PathParam("id") String id, Permission permission)
{
@@ -197,16 +199,7 @@ public abstract class AbstractPermissionResource
//~--- get methods ----------------------------------------------------------
/**
- * Returns the {@link Permission} with the specified id.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, permission id does not belong to the user or group
- * - 404 not found, no permission with the specified id available
- * - 500 internal server error
- *
- *
+ * Returns the {@link Permission} with the specified id.
*
* @param id id of the {@link Permission}
*
@@ -214,6 +207,12 @@ public abstract class AbstractPermissionResource
*/
@GET
@Path("{id}")
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, permission id does not belong to the user or group"),
+ @ResponseCode(code = 404, condition = "not found, no permission with the specified id available"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Permission get(@PathParam("id") String id)
{
@@ -223,17 +222,15 @@ public abstract class AbstractPermissionResource
}
/**
- * Returns all permissions of the user or group managed by the resource.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 500 internal server error
- *
+ * Returns all permissions of the user or group managed by the resource.
*
* @return all permissions of the user or group
*/
@GET
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "success"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public List getAll()
{
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java
index 0fd7518795..54c9369a57 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java
@@ -111,6 +111,7 @@ public class PluginResource
* Installs a plugin from a package.
*
* @param uploadedInputStream
+ *
* @return
*
* @throws IOException
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java
index 4232ecda9d..9382f58c5c 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java
@@ -71,6 +71,9 @@ import static com.google.common.base.Preconditions.*;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.multipart.FormDataParam;
+import com.webcohesion.enunciate.metadata.rs.ResponseCode;
+import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
+import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint;
import java.io.File;
@@ -139,17 +142,8 @@ public class RepositoryImportResource
/**
* Imports a repository type specific bundle. The bundle file is uploaded to
* the server which is running scm-manager. After the upload has finished, the
- * bundle file is passed to the {@link UnbundleCommandBuilder}. This method
- * requires admin privileges.
- *
- * Status codes:
- *
- * - 201 created
- * - 400 bad request, the import bundle feature is not supported by this
- * type of repositories or the parameters are not valid.
- * - 500 internal server error
- * - 409 conflict, a repository with the name already exists.
- *
+ * bundle file is passed to the {@link UnbundleCommandBuilder}. Note: This method
+ * requires admin privileges.
*
* @param uriInfo uri info
* @param type repository type
@@ -157,12 +151,23 @@ public class RepositoryImportResource
* @param inputStream input bundle
* @param compressed true if the bundle is gzip compressed
*
- * @return empty response with location header which points to the imported
- * repository
+ * @return empty response with location header which points to the imported repository
* @since 1.43
*/
@POST
@Path("{type}/bundle")
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "created", additionalHeaders = {
+ @ResponseHeader(name = "Location", description = "uri to the imported repository")
+ }),
+ @ResponseCode(
+ code = 400,
+ condition = "bad request, the import bundle feature is not supported by this type of repositories or the parameters are not valid"
+ ),
+ @ResponseCode(code = 409, condition = "conflict, a repository with the name already exists"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response importFromBundle(@Context UriInfo uriInfo,
@PathParam("type") String type, @FormDataParam("name") String name,
@@ -179,18 +184,8 @@ public class RepositoryImportResource
* This method works exactly like
* {@link #importFromBundle(UriInfo, String, String, InputStream)}, but this
* method returns an html content-type. The method exists only for a
- * workaround of the javascript ui extjs. This method requires admin
- * privileges.
- *
- * Status codes:
- *
- * - 201 created
- * - 400 bad request, the import bundle feature is not supported by this
- * type of repositories or the parameters are not valid.
- * - 500 internal server error
- * - 409 conflict, a repository with the name already exists.
- *
- *
+ * workaround of the javascript ui extjs. Note: This method requires admin
+ * privileges.
*
* @param type repository type
* @param name name of the repository
@@ -203,6 +198,16 @@ public class RepositoryImportResource
*/
@POST
@Path("{type}/bundle.html")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(
+ code = 400,
+ condition = "bad request, the import bundle feature is not supported by this type of repositories or the parameters are not valid"
+ ),
+ @ResponseCode(code = 409, condition = "conflict, a repository with the name already exists"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(RestActionUploadResult.class)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_HTML)
public Response importFromBundleUI(@PathParam("type") String type,
@@ -231,16 +236,7 @@ public class RepositoryImportResource
* Imports a external repository which is accessible via url. The method can
* only be used, if the repository type supports the {@link Command#PULL}. The
* method will return a location header with the url to the imported
- * repository. This method requires admin privileges.
- *
- * Status codes:
- *
- * - 201 created
- * - 400 bad request, the import by url feature is not supported by this
- * type of repositories or the parameters are not valid.
- * - 409 conflict, a repository with the name already exists.
- * - 500 internal server error
- *
+ * repository. Note: This method requires admin privileges.
*
* @param uriInfo uri info
* @param type repository type
@@ -252,6 +248,18 @@ public class RepositoryImportResource
*/
@POST
@Path("{type}/url")
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "created", additionalHeaders = {
+ @ResponseHeader(name = "Location", description = "uri to the imported repository")
+ }),
+ @ResponseCode(
+ code = 400,
+ condition = "bad request, the import feature is not supported by this type of repositories or the parameters are not valid"
+ ),
+ @ResponseCode(code = 409, condition = "conflict, a repository with the name already exists"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response importFromUrl(@Context UriInfo uriInfo,
@PathParam("type") String type, UrlImportRequest request)
@@ -295,15 +303,7 @@ public class RepositoryImportResource
/**
* Imports repositories of the given type from the configured repository
- * directory. This method requires admin privileges.
- *
- * Status codes:
- *
- * - 200 ok, successful
- * - 400 bad request, the import feature is not
- * supported by this type of repositories.
- * - 500 internal server error
- *
+ * directory. Note: This method requires admin privileges.
*
* @param type repository type
*
@@ -311,6 +311,14 @@ public class RepositoryImportResource
*/
@POST
@Path("{type}")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(
+ code = 400,
+ condition = "bad request, the import feature is not supported by this type of repositories"
+ ),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(Repository[].class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response importRepositories(@PathParam("type") String type)
@@ -330,19 +338,19 @@ public class RepositoryImportResource
/**
* Imports repositories of all supported types from the configured repository
- * directories. This method requires admin privileges.
- *
- * Status codes:
- *
- * - 200 ok, successful
- * - 400 bad request, the import feature is not
- * supported by this type of repositories.
- * - 500 internal server error
- *
+ * directories. Note: This method requires admin privileges.
*
* @return imported repositories
*/
@POST
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(
+ code = 400,
+ condition = "bad request, the import feature is not supported by this type of repositories"
+ ),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(Repository[].class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response importRepositories()
@@ -368,15 +376,7 @@ public class RepositoryImportResource
/**
* Imports repositories of the given type from the configured repository
* directory. Returns a list of successfully imported directories and a list
- * of failed directories. This method requires admin privileges.
- *
- * Status codes:
- *
- * - 200 ok, successful
- * - 400 bad request, the import feature is not
- * supported by this type of repositories.
- * - 500 internal server error
- *
+ * of failed directories. Note: This method requires admin privileges.
*
* @param type repository type
*
@@ -385,6 +385,14 @@ public class RepositoryImportResource
*/
@POST
@Path("{type}/directory")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(
+ code = 400,
+ condition = "bad request, the import feature is not supported by this type of repositories"
+ ),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(ImportResult.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response importRepositoriesFromDirectory(
@@ -453,22 +461,20 @@ public class RepositoryImportResource
/**
* Returns a list of repository types, which support the directory import
- * feature.
- *
- * This method requires admin privileges.
- *
- * Status codes:
- *
- * - 200 ok, successful
- * - 400 bad request, the import feature is not
- * supported by this type of repositories.
- * - 500 internal server error
- *
+ * feature. Note: This method requires admin privileges.
*
* @return list of repository types
*/
@GET
@TypeHint(Type[].class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(
+ code = 400,
+ condition = "bad request, the import feature is not supported by this type of repositories"
+ ),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getImportableTypes()
{
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java
index be0a2ec603..16168aefc7 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java
@@ -39,6 +39,9 @@ import com.google.common.base.Strings;
import com.google.common.io.Closeables;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.webcohesion.enunciate.metadata.rs.ResponseCode;
+import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
+import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint;
import org.apache.shiro.SecurityUtils;
@@ -104,13 +107,13 @@ import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriInfo;
/**
- *
+ * Repository related RESTful Web Service Endpoint.
+ *
* @author Sebastian Sdorra
*/
@Singleton
@Path("repositories")
-public class RepositoryResource
- extends AbstractManagerResource
+public class RepositoryResource extends AbstractManagerResource
{
/** Field description */
@@ -147,22 +150,22 @@ public class RepositoryResource
//~--- methods --------------------------------------------------------------
/**
- * Creates a new repository.
- * This method requires admin privileges.
- *
- * Status codes:
- *
- * - 201 create success
- * - 403 forbidden, the current user has no admin privileges
- * - 500 internal server error
- *
+ * Creates a new repository.Note: This method requires admin privileges.
*
* @param uriInfo current uri informations
* @param repository the repository to be created
*
- * @return
+ * @return empty response with location header to the new repository
*/
@POST
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "success", additionalHeaders = {
+ @ResponseHeader(name = "Location", description = "uri to the new created repository")
+ }),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Override
public Response create(@Context UriInfo uriInfo, Repository repository)
@@ -171,19 +174,7 @@ public class RepositoryResource
}
/**
- * Deletes a repository.
- * This method requires owner privileges.
- *
- * Status codes:
- *
- * - 201 delete success
- * - 403 forbidden, the current user has no owner privileges
- * -
- * 412 forbidden, the repository is not archived,
- * this error occurs only with enabled repository archive.
- *
- * - 500 internal server error
- *
+ * Deletes a repository. Note: This method requires owner privileges.
*
* @param id the id of the repository to delete.
*
@@ -191,6 +182,17 @@ public class RepositoryResource
*/
@DELETE
@Path("{id}")
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "delete success"),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no owner privileges"),
+ @ResponseCode(code = 404, condition = "could not find repository"),
+ @ResponseCode(
+ code = 412,
+ condition = "precondition failed, the repository is not archived, this error occurs only with enabled repository archive"
+ ),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Override
public Response delete(@PathParam("id") String id)
{
@@ -232,20 +234,20 @@ public class RepositoryResource
}
/**
- * Re run repository health checks.
- * Status codes:
- *
- * - 201 re run success
- * - 403 forbidden, the current user has no owner privileges
- * - 404 could not find repository
- * - 500 internal server error
- *
+ * Re run repository health checks.
*
* @param id id of the repository
*
* @return
*/
@POST
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "re run success"),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no owner privileges"),
+ @ResponseCode(code = 404, condition = "could not find repository"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Path("{id}/healthcheck")
public Response runHealthChecks(@PathParam("id") String id)
{
@@ -254,6 +256,7 @@ public class RepositoryResource
try
{
healthChecker.check(id);
+ // TODO should return 204 instead of 200
response = Response.ok().build();
}
catch (RepositoryNotFoundException ex)
@@ -276,15 +279,7 @@ public class RepositoryResource
}
/**
- * Modifies the given repository.
- * This method requires owner privileges.
- *
- * Status codes:
- *
- * - 201 update successful
- * - 403 forbidden, the current user has no owner privileges
- * - 500 internal server error
- *
+ * Modifies the given repository. Note: This method requires owner privileges.
*
* @param uriInfo current uri informations
* @param id id of the repository to be modified
@@ -294,10 +289,16 @@ public class RepositoryResource
*/
@PUT
@Path("{id}")
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "update successful"),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no owner privileges"),
+ @ResponseCode(code = 404, condition = "could not find repository"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Override
- public Response update(@Context UriInfo uriInfo, @PathParam("id") String id,
- Repository repository)
+ public Response update(@Context UriInfo uriInfo, @PathParam("id") String id, Repository repository)
{
return super.update(uriInfo, id, repository);
}
@@ -305,14 +306,7 @@ public class RepositoryResource
//~--- get methods ----------------------------------------------------------
/**
- * Returns the {@link Repository} with the specified id.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 404 not found, no repository with the specified id available
- * - 500 internal server error
- *
+ * Returns the {@link Repository} with the specified id.
*
* @param request the current request
* @param id the id/name of the user
@@ -322,6 +316,11 @@ public class RepositoryResource
@GET
@Path("{id}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 404, condition = "not found, no repository with the specified id available"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(Repository.class)
@Override
public Response get(@Context Request request, @PathParam("id") String id)
@@ -330,13 +329,7 @@ public class RepositoryResource
}
/**
- * Returns all repositories.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 500 internal server error
- *
+ * Returns all repositories.
*
* @param request the current request
* @param start the start value for paging
@@ -348,6 +341,10 @@ public class RepositoryResource
*/
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(Repository[].class)
@Override
public Response getAll(@Context Request request, @DefaultValue("0")
@@ -360,16 +357,7 @@ public class RepositoryResource
}
/**
- * Returns a annotate/blame view for the given path.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the blame feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or the path could not be found
- * - 500 internal server error
- *
+ * Returns a annotate/blame view for the given path.
*
* @param id the id of the repository
* @param revision the revision of the file
@@ -382,6 +370,12 @@ public class RepositoryResource
*/
@GET
@Path("{id}/blame")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the blame feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository or the path could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(BlameResult.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getBlame(@PathParam("id") String id,
@@ -435,16 +429,7 @@ public class RepositoryResource
}
/**
- * Returns all {@link Branches} of a repository.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the content feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or the path could not be found
- * - 500 internal server error
- *
+ * Returns all {@link Branches} of a repository.
*
* @param id the id of the repository
*
@@ -457,6 +442,14 @@ public class RepositoryResource
*/
@GET
@Path("{id}/branches")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the branch feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(Branches.class)
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getBranches(@PathParam("id") String id)
throws RepositoryException, IOException
{
@@ -495,16 +488,7 @@ public class RepositoryResource
}
/**
- * Returns a list of folders and files for the given folder.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the browse feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or the path could not be found
- * - 500 internal server error
- *
+ * Returns a list of folders and files for the given folder.
*
* @param id the id of the repository
* @param revision the revision of the file
@@ -520,6 +504,12 @@ public class RepositoryResource
*/
@GET
@Path("{id}/browse")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the browse feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository or the path could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(BrowserResult.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
//J-
@@ -586,15 +576,7 @@ public class RepositoryResource
}
/**
- * Returns the {@link Repository} with the specified type and name.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 404 not found,
- * no repository with the specified type and name available
- * - 500 internal server error
- *
+ * Returns the {@link Repository} with the specified type and name.
*
* @param type the type of the repository
* @param name the name of the repository
@@ -603,8 +585,13 @@ public class RepositoryResource
*/
@GET
@Path("{type: [a-z]+}/{name: .*}")
- @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 404, condition = "not found, no repository with the specified type and name available"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(Repository.class)
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getByTypeAndName(@PathParam("type") String type,
@PathParam("name") String name)
{
@@ -626,17 +613,7 @@ public class RepositoryResource
/**
* Returns the {@link Changeset} from the given repository
- * with the specified revision.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the changeset feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or
- * the revision could not be found
- * - 500 internal server error
- *
+ * with the specified revision.
*
* @param id the id of the repository
* @param revision the revision of the changeset
@@ -648,6 +625,14 @@ public class RepositoryResource
*/
@GET
@Path("{id}/changeset/{revision}")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the changeset feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository or the revision could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(Changeset.class)
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getChangeset(@PathParam("id") String id,
@PathParam("revision") String revision)
throws IOException, RepositoryException
@@ -700,16 +685,7 @@ public class RepositoryResource
}
/**
- * Returns a list of {@link Changeset} for the given repository.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the changeset feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or the path could not be found
- * - 500 internal server error
- *
+ * Returns a list of {@link Changeset} for the given repository.
*
* @param id the id of the repository
* @param path path of a file
@@ -725,6 +701,12 @@ public class RepositoryResource
*/
@GET
@Path("{id}/changesets")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the changeset feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository or the path could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(ChangesetPagingResult.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
//J-
@@ -793,16 +775,7 @@ public class RepositoryResource
}
/**
- * Returns the content of a file.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the content feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or the path could not be found
- * - 500 internal server error
- *
+ * Returns the content of a file.
*
* @param id the id of the repository
* @param revision the revision of the file
@@ -812,14 +785,20 @@ public class RepositoryResource
*/
@GET
@Path("{id}/content")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the content feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository or the path could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(StreamingOutput.class)
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
public Response getContent(@PathParam("id") String id,
@QueryParam("revision") String revision, @QueryParam("path") String path)
{
- Response response = null;
- StreamingOutput output = null;
- RepositoryService service = null;
+ Response response;
+ StreamingOutput output;
+ RepositoryService service;
try
{
@@ -864,16 +843,7 @@ public class RepositoryResource
}
/**
- * Returns the modifications of a {@link Changeset}.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the content feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or the path could not be found
- * - 500 internal server error
- *
+ * Returns the modifications of a {@link Changeset}.
*
* @param id the id of the repository
* @param revision the revision of the file
@@ -887,6 +857,12 @@ public class RepositoryResource
*/
@GET
@Path("{id}/diff")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the diff feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository or the path could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@TypeHint(DiffStreamingOutput.class)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getDiff(@PathParam("id") String id,
@@ -903,8 +879,8 @@ public class RepositoryResource
*/
HttpUtil.checkForCRLFInjection(revision);
- RepositoryService service = null;
- Response response = null;
+ RepositoryService service;
+ Response response;
try
{
@@ -952,16 +928,7 @@ public class RepositoryResource
}
/**
- * Returns all {@link Tags} of a repository.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 400 bad request, the content feature is not
- * supported by this type of repositories.
- * - 404 not found, if the repository or the path could not be found
- * - 500 internal server error
- *
+ * Returns all {@link Tags} of a repository.
*
* @param id the id of the repository
*
@@ -974,6 +941,14 @@ public class RepositoryResource
*/
@GET
@Path("{id}/tags")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "bad request, the tag feature is not supported by this type of repositories."),
+ @ResponseCode(code = 404, condition = "not found, the repository could not be found"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(Tags.class)
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getTags(@PathParam("id") String id)
throws RepositoryException, IOException
{
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java
index 3b4606682a..3c7c9b8785 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java
@@ -38,6 +38,8 @@ package sonia.scm.api.rest.resources;
import com.google.common.base.Function;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.webcohesion.enunciate.metadata.rs.ResponseCode;
+import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import sonia.scm.HandlerEvent;
import sonia.scm.cache.Cache;
@@ -61,7 +63,9 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
/**
- *
+ * RESTful Web Service Resource to search users and groups. This endpoint can be used to implement typeahead input
+ * fields for permissions.
+ *
* @author Sebastian Sdorra
*/
@Singleton
@@ -138,12 +142,7 @@ public class SearchResource implements UserListener, GroupListener
}
/**
- * Returns a list of groups found by the given search string.
- *
- *
- * - 200 success
- * - 500 internal server error
- *
+ * Returns a list of groups found by the given search string.
*
* @param queryString the search string
*
@@ -151,6 +150,10 @@ public class SearchResource implements UserListener, GroupListener
*/
@GET
@Path("groups")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public SearchResults searchGroups(@QueryParam("query") String queryString)
{
@@ -174,12 +177,7 @@ public class SearchResource implements UserListener, GroupListener
}
/**
- * Returns a list of users found by the given search string.
- *
- *
- * - 200 success
- * - 500 internal server error
- *
+ * Returns a list of users found by the given search string.
*
* @param queryString the search string
*
@@ -187,6 +185,10 @@ public class SearchResource implements UserListener, GroupListener
*/
@GET
@Path("users")
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public SearchResults searchUsers(@QueryParam("query") String queryString)
{
@@ -208,8 +210,8 @@ public class SearchResource implements UserListener, GroupListener
//~--- fields ---------------------------------------------------------------
/** Field description */
- private SearchHandler groupSearchHandler;
+ private final SearchHandler groupSearchHandler;
/** Field description */
- private SearchHandler userSearchHandler;
+ private final SearchHandler userSearchHandler;
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SecuritySystemResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SecuritySystemResource.java
index d97b21110b..f9e95232db 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SecuritySystemResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SecuritySystemResource.java
@@ -47,7 +47,8 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
/**
- *
+ * Resource for managing system security permissions.
+ *
* @author Sebastian Sdorra
*/
@Path("security/permission")
@@ -72,31 +73,28 @@ public class SecuritySystemResource
//~--- get methods ----------------------------------------------------------
/**
- * Method description
+ * Returns group permission sub resource.
*
+ * @param group name of group
*
- * @param group
- *
- * @return
+ * @return sub resource
*/
@Path("group/{group}")
- public GroupPermissionResource getGroupSubResource(
- @PathParam("group") String group)
+ public GroupPermissionResource getGroupSubResource(@PathParam("group") String group)
{
return new GroupPermissionResource(system, group);
}
/**
- * Method description
+ * Returns user permission sub resource.
*
*
- * @param user
+ * @param user name of user
*
- * @return
+ * @return sub resource
*/
@Path("user/{user}")
- public UserPermissionResource getUserSubResource(
- @PathParam("user") String user)
+ public UserPermissionResource getUserSubResource(@PathParam("user") String user)
{
return new UserPermissionResource(system, user);
}
@@ -104,5 +102,5 @@ public class SecuritySystemResource
//~--- fields ---------------------------------------------------------------
/** Field description */
- private SecuritySystem system;
+ private final SecuritySystem system;
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java
index e76d185ed2..ed384071b1 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java
@@ -37,6 +37,9 @@ package sonia.scm.api.rest.resources;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.webcohesion.enunciate.metadata.rs.ResponseCode;
+import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
+import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint;
import org.apache.shiro.SecurityUtils;
@@ -71,7 +74,8 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
/**
- *
+ * RESTful Web Service Resource to manage users.
+ *
* @author Sebastian Sdorra
*/
@Singleton
@@ -96,8 +100,7 @@ public class UserResource extends AbstractManagerResource
* @param securityContextProvider
*/
@Inject
- public UserResource(UserManager userManager,
- EncryptionHandler encryptionHandler)
+ public UserResource(UserManager userManager, EncryptionHandler encryptionHandler)
{
super(userManager);
this.encryptionHandler = encryptionHandler;
@@ -106,15 +109,7 @@ public class UserResource extends AbstractManagerResource
//~--- methods --------------------------------------------------------------
/**
- * Creates a new user.
- * This method requires admin privileges.
- *
- * Status codes:
- *
- * - 201 create success
- * - 403 forbidden, the current user has no admin privileges
- * - 500 internal server error
- *
+ * Creates a new user. Note: This method requires admin privileges.
*
* @param uriInfo current uri informations
* @param user the user to be created
@@ -122,6 +117,14 @@ public class UserResource extends AbstractManagerResource
* @return
*/
@POST
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "create success", additionalHeaders = {
+ @ResponseHeader(name = "Location", description = "uri to the created group")
+ }),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Override
public Response create(@Context UriInfo uriInfo, User user)
@@ -130,15 +133,7 @@ public class UserResource extends AbstractManagerResource
}
/**
- * Deletes a user.
- * This method requires admin privileges.
- *
- * Status codes:
- *
- * - 201 delete success
- * - 403 forbidden, the current user has no admin privileges
- * - 500 internal server error
- *
+ * Deletes a user. Note: This method requires admin privileges.
*
* @param name the name of the user to delete.
*
@@ -146,6 +141,12 @@ public class UserResource extends AbstractManagerResource
*/
@DELETE
@Path("{id}")
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "delete success"),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Override
public Response delete(@PathParam("id") String name)
{
@@ -153,15 +154,7 @@ public class UserResource extends AbstractManagerResource
}
/**
- * Modifies the given user.
- * This method requires admin privileges.
- *
- * Status codes:
- *
- * - 201 update successful
- * - 403 forbidden, the current user has no admin privileges
- * - 500 internal server error
- *
+ * Modifies the given user. Note: This method requires admin privileges.
*
* @param uriInfo current uri informations
* @param name name of the user to be modified
@@ -171,6 +164,12 @@ public class UserResource extends AbstractManagerResource
*/
@PUT
@Path("{id}")
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "update success"),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ @TypeHint(TypeHint.NO_CONTENT.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Override
public Response update(@Context UriInfo uriInfo,
@@ -182,16 +181,7 @@ public class UserResource extends AbstractManagerResource
//~--- get methods ----------------------------------------------------------
/**
- * Returns a user.
- * This method requires admin privileges.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 403 forbidden, the current user has no admin privileges
- * - 404 not found, no user with the specified id/name available
- * - 500 internal server error
- *
+ * Returns a user. Note: This method requires admin privileges.
*
* @param request the current request
* @param id the id/name of the user
@@ -201,6 +191,12 @@ public class UserResource extends AbstractManagerResource
@GET
@Path("{id}")
@TypeHint(User.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"),
+ @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Override
public Response get(@Context Request request, @PathParam("id") String id)
@@ -220,15 +216,7 @@ public class UserResource extends AbstractManagerResource
}
/**
- * Returns all users.
- * This method requires admin privileges.
- *
- * Status codes:
- *
- * - 200 get successful
- * - 403 forbidden, the current user has no admin privileges
- * - 500 internal server error
- *
+ * Returns all users. Note: This method requires admin privileges.
*
* @param request the current request
* @param start the start value for paging
@@ -240,6 +228,11 @@ public class UserResource extends AbstractManagerResource
*/
@GET
@TypeHint(User[].class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Override
public Response getAll(@Context Request request, @DefaultValue("0")
@@ -253,14 +246,6 @@ public class UserResource extends AbstractManagerResource
//~--- methods --------------------------------------------------------------
- /**
- * Method description
- *
- *
- * @param items
- *
- * @return
- */
@Override
protected GenericEntity> createGenericEntity(
Collection items)
@@ -269,24 +254,12 @@ public class UserResource extends AbstractManagerResource
;
}
- /**
- * Method description
- *
- *
- * @param user
- */
@Override
protected void preCreate(User user)
{
encryptPassword(user);
}
-
- /**
- * Method description
- *
- *
- * @param user
- */
+
@Override
protected void preUpate(User user)
{
@@ -303,14 +276,6 @@ public class UserResource extends AbstractManagerResource
}
}
- /**
- * Method description
- *
- *
- * @param users
- *
- * @return
- */
@Override
protected Collection prepareForReturn(Collection users)
{
@@ -325,14 +290,6 @@ public class UserResource extends AbstractManagerResource
return users;
}
- /**
- * Method description
- *
- *
- * @param user
- *
- * @return
- */
@Override
protected User prepareForReturn(User user)
{
@@ -341,42 +298,18 @@ public class UserResource extends AbstractManagerResource
return user;
}
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param user
- *
- * @return
- */
@Override
protected String getId(User user)
{
return user.getName();
}
- /**
- * Method description
- *
- *
- * @return
- */
@Override
protected String getPathPart()
{
return PATH_PART;
}
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param user
- */
private void encryptPassword(User user)
{
String password = user.getPassword();