Former-commit-id: 39621f5811
restapi
Jens Pelzetter 2020-08-09 12:46:17 +02:00
parent 3a72c79cd8
commit 34303af9fc
1 changed files with 112 additions and 6 deletions

View File

@ -20,7 +20,6 @@ package org.libreccm.api.themes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege;
@ -36,12 +35,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.rmi.UnexpectedException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -73,6 +69,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* Provides a RESTful API for managing themes.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ -84,17 +81,25 @@ public class Themes implements Serializable {
private static final Logger LOGGER = LogManager.getLogger(Themes.class);
/**
* The available theme providers.
*/
@Inject
@Any
private Instance<ThemeProvider> providers;
/**
* Lists the available theme providers.
*
* @return A list of the fully qualified class names of the available theme
* providers.
*/
@GET
@Path("/providers")
@Produces(MediaType.APPLICATION_JSON)
@AuthorizationRequired
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
public List<String> getThemeProviders() {
return providers
.stream()
.filter(
@ -105,6 +110,11 @@ public class Themes implements Serializable {
.collect(Collectors.toList());
}
/**
* Gets a list of all available themes.
*
* @return A list of all available themes.
*/
@GET
@Path("/themes")
@Produces(MediaType.APPLICATION_JSON)
@ -121,6 +131,13 @@ public class Themes implements Serializable {
.collect(Collectors.toList());
}
/**
* Gets the {@link ThemeInfo} for a specific theme.
*
* @param themeName The name of the theme.
*
* @return The {@link ThemeInfo} for the theme.
*/
@GET
@Path("/themes/{theme}")
@Produces(MediaType.APPLICATION_JSON)
@ -156,6 +173,15 @@ public class Themes implements Serializable {
);
}
/**
* Creates a new theme.
*
* @param themeName The name of the new theme.
*
* @param providerName The provider to use for the new theme.
*
* @return The {@link ThemeInfo} for the new theme.
*/
@PUT
@Path("/themes/{theme}")
@Produces(MediaType.APPLICATION_JSON)
@ -193,6 +219,13 @@ public class Themes implements Serializable {
return provider.createTheme(themeName);
}
/**
* Deletes a theme.
*
* @param themeName The theme to delete.
*
* @return A response indicating success or failure.
*/
@DELETE
@Path("/themes/{theme}")
@AuthorizationRequired
@ -214,6 +247,13 @@ public class Themes implements Serializable {
return Response.ok().build();
}
/**
* Publishes a theme.
*
* @param themeName The name of theme to publish.
*
* @return A response indicating success or failure.
*/
@POST
@Path("/themes/{theme}/live")
@AuthorizationRequired
@ -233,6 +273,13 @@ public class Themes implements Serializable {
return Response.ok().build();
}
/**
* Unpublishes a theme.
*
* @param themeName The name of theme to unpublish.
*
* @return A response indicating success or failure.
*/
@DELETE
@Path("/themes/{theme}/live")
@AuthorizationRequired
@ -252,6 +299,13 @@ public class Themes implements Serializable {
return Response.ok().build();
}
/**
* Gets the files in the root directory of the theme.
*
* @param themeName The name of the name.
*
* @return A list of files in the root directory of the theme.
*/
@GET
@Path("/themes/{theme}/files/")
@AuthorizationRequired
@ -294,6 +348,14 @@ public class Themes implements Serializable {
}
}
/**
* Gets a file from the theme.
*
* @param themeName The name of the theme.
* @param path The path of the file to retrieve.
*
* @return The content of the requsted file.
*/
@GET
@Path("/themes/{theme}/files/{path:.+}")
@AuthorizationRequired
@ -350,6 +412,15 @@ public class Themes implements Serializable {
}
}
/**
* Creates or updates a file in a theme.
*
* @param themeName The name of the theme.
* @param path The path of file to create or update.
* @param data The contents of the file.
*
* @return A response indicating success or failure.
*/
@PUT
@Path("/themes/{theme}/files/{path:.+}")
@AuthorizationRequired
@ -401,6 +472,16 @@ public class Themes implements Serializable {
return Response.ok().build();
}
/**
* Removes a file from a theme
*
* @param themeName The name of the theme.
* @param path The path of the file to delete.
* @param recursive If the file is a directory: Delete the directory and all
* its content?
*
* @return A response indicating success or failure.
*/
@DELETE
@Path("/themes/{theme}/files/{path:.+}")
@AuthorizationRequired
@ -457,6 +538,13 @@ public class Themes implements Serializable {
}
}
/**
* Downloads a theme as ZIP file.
*
* @param themeName The name of the theme to download.
*
* @return A response with a ZIP file containing all files or the theme.
*/
@GET
@Path("/themes/{theme}/@download")
@Produces("application/zip")
@ -492,6 +580,24 @@ public class Themes implements Serializable {
}
}
/**
* Updates a theme from a ZIP file. The method checks each file in the ZIP
* and in the theme and does to following:
* <ul>
* <li>If the files (their checksums) are identical, do nothing</li>
* <li>If the checksums differ: Update the file in the theme with the file
* from the ZIP file.</li>
* <li>If the file exists only in the ZIP: Create the file in the
* theme.</li>
* <li>If the file exists only in the theme: Remove the file from the
* theme.</li>
* </ul>
*
* @param themeName The name of the theme to update.
* @param updatedTheme The ZIP file containing the updated theme.
*
* @return A response indicating success or failure.
*/
@POST
@Path("/themes/{theme}/@update")
@Consumes("application/zip")
@ -558,7 +664,7 @@ public class Themes implements Serializable {
if (!MessageDigest.isEqual(
fromZipChecksum, fromThemeChecksum
)) {
try(OutputStream outputStream = provider
try (OutputStream outputStream = provider
.getOutputStreamForThemeFile(themeName, path)) {
outputStream.write(bytesFromZip);
}