diff --git a/ccm-core/src/main/java/org/libreccm/api/themes/Themes.java b/ccm-core/src/main/java/org/libreccm/api/themes/Themes.java
index 17891cf84..218ab2f49 100644
--- a/ccm-core/src/main/java/org/libreccm/api/themes/Themes.java
+++ b/ccm-core/src/main/java/org/libreccm/api/themes/Themes.java
@@ -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 Jens Pelzetter
*/
@@ -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 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 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:
+ *
+ * - If the files (their checksums) are identical, do nothing
+ * - If the checksums differ: Update the file in the theme with the file
+ * from the ZIP file.
+ * - If the file exists only in the ZIP: Create the file in the
+ * theme.
+ * - If the file exists only in the theme: Remove the file from the
+ * theme.
+ *
+ *
+ * @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);
}