CCM NG: Second part of api for theme manager app
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5692 8810af33-2d31-482b-a856-94f89814c4df
parent
4297bbc4cc
commit
db9e9b9cfd
|
|
@ -44,7 +44,6 @@ import java.nio.file.Path;
|
|||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.rmi.UnexpectedException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
|
@ -234,14 +233,16 @@ public class NIOFileSystemAdapter implements FileSystemAdapter {
|
|||
final String targetPath,
|
||||
boolean recursive) throws FileAccessException {
|
||||
|
||||
final Path nioSourcePath = Paths.get(sourcePath);
|
||||
final Path nioTargetPath = Paths.get(targetPath);
|
||||
final Path nioSourcePath = Paths
|
||||
.get(String.join("/", dataPath, sourcePath));
|
||||
final Path nioTargetPath = Paths
|
||||
.get(String.join("/", dataPath, targetPath));
|
||||
|
||||
if (recursive) {
|
||||
|
||||
try {
|
||||
Files.walkFileTree(
|
||||
nioTargetPath,
|
||||
nioSourcePath,
|
||||
new FileVisitor<Path>() {
|
||||
|
||||
@Override
|
||||
|
|
@ -262,7 +263,7 @@ public class NIOFileSystemAdapter implements FileSystemAdapter {
|
|||
file,
|
||||
nioTargetPath
|
||||
.resolve(nioSourcePath.relativize(file)),
|
||||
StandardCopyOption.ATOMIC_MOVE,
|
||||
// StandardCopyOption.ATOMIC_MOVE,
|
||||
StandardCopyOption.COPY_ATTRIBUTES,
|
||||
StandardCopyOption.REPLACE_EXISTING,
|
||||
LinkOption.NOFOLLOW_LINKS);
|
||||
|
|
@ -311,7 +312,7 @@ public class NIOFileSystemAdapter implements FileSystemAdapter {
|
|||
try {
|
||||
Files.copy(nioSourcePath,
|
||||
nioTargetPath,
|
||||
StandardCopyOption.ATOMIC_MOVE,
|
||||
// StandardCopyOption.ATOMIC_MOVE,
|
||||
StandardCopyOption.COPY_ATTRIBUTES,
|
||||
StandardCopyOption.REPLACE_EXISTING,
|
||||
LinkOption.NOFOLLOW_LINKS);
|
||||
|
|
@ -325,14 +326,16 @@ public class NIOFileSystemAdapter implements FileSystemAdapter {
|
|||
public void move(final String sourcePath, final String targetPath)
|
||||
throws FileAccessException {
|
||||
|
||||
final Path nioSourcePath = Paths.get(sourcePath);
|
||||
final Path nioTargetPath = Paths.get(targetPath);
|
||||
final Path nioSourcePath = Paths.get(
|
||||
String.join("/", dataPath, sourcePath));
|
||||
final Path nioTargetPath = Paths.get(
|
||||
String.join("/", dataPath, targetPath));
|
||||
|
||||
try {
|
||||
Files.move(nioSourcePath,
|
||||
nioTargetPath,
|
||||
StandardCopyOption.ATOMIC_MOVE,
|
||||
StandardCopyOption.COPY_ATTRIBUTES,
|
||||
// StandardCopyOption.COPY_ATTRIBUTES,
|
||||
StandardCopyOption.REPLACE_EXISTING,
|
||||
LinkOption.NOFOLLOW_LINKS);
|
||||
} catch(IOException ex) {
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String BASE_PATH = "/themes";
|
||||
private static final String DRAFT_THEMES_PATH = "/themes" + "/draft";
|
||||
private static final String LIVE_THEMES_PATH = "/themes" + "/live";
|
||||
private static final String DRAFT_THEMES_PATH = BASE_PATH + "/draft";
|
||||
private static final String LIVE_THEMES_PATH = BASE_PATH + "/live";
|
||||
|
||||
private static final String THEME_JSON = "%s/theme.json";
|
||||
private static final String THEME_XML = "%s/theme.xml";
|
||||
|
|
@ -175,7 +175,7 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
try(final OutputStreamWriter writer = new OutputStreamWriter(
|
||||
try (final OutputStreamWriter writer = new OutputStreamWriter(
|
||||
outputStream, StandardCharsets.UTF_8)) {
|
||||
writer
|
||||
.append(manifestUtil
|
||||
|
|
@ -320,20 +320,50 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
ThemeVersion.DRAFT);
|
||||
final String liveThemePath = createThemePath(theme,
|
||||
ThemeVersion.LIVE);
|
||||
final String liveThemePathTmp = String.format("%_tmp", liveThemePath);
|
||||
final String liveThemePathTmp = String.format("%s_tmp", liveThemePath);
|
||||
|
||||
try {
|
||||
if (!ccmFiles.existsFile(LIVE_THEMES_PATH)) {
|
||||
ccmFiles.createDirectory(LIVE_THEMES_PATH);
|
||||
}
|
||||
} catch (FileAccessException
|
||||
| InsufficientPermissionsException
|
||||
| FileAlreadyExistsException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
ccmFiles.createDirectory(liveThemePathTmp);
|
||||
|
||||
ccmFiles.copyFile(draftThemePath, liveThemePathTmp, true);
|
||||
if (ccmFiles.existsFile(liveThemePath)) {
|
||||
ccmFiles.deleteFile(liveThemePath, true);
|
||||
}
|
||||
|
||||
ccmFiles.moveFile(liveThemePathTmp, liveThemePath);
|
||||
|
||||
} catch (DirectoryNotEmptyException
|
||||
| FileAccessException
|
||||
| FileAlreadyExistsException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unpublishTheme(final String theme) {
|
||||
|
||||
final String liveThemePath = createThemePath(theme,
|
||||
ThemeVersion.LIVE);
|
||||
try {
|
||||
ccmFiles.deleteFile(liveThemePath, true);
|
||||
} catch (DirectoryNotEmptyException
|
||||
| FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
throw new UnexpectedErrorException();
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -357,15 +387,19 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
|
||||
final ThemeManifest manifest;
|
||||
try {
|
||||
final InputStream inputStream = ccmFiles
|
||||
.createInputStream(String.format(THEME_JSON,
|
||||
themePath));
|
||||
if (ccmFiles.existsFile(String.format(THEME_JSON,
|
||||
themePath))) {
|
||||
|
||||
final String jsonPath = String.format(
|
||||
DRAFT_THEMES_PATH + "/" + THEME_JSON, themePath);
|
||||
final String xmlPath = String.format(
|
||||
DRAFT_THEMES_PATH + "/" + THEME_XML, themePath);
|
||||
|
||||
if (ccmFiles.existsFile(jsonPath)) {
|
||||
final InputStream inputStream = ccmFiles
|
||||
.createInputStream(jsonPath);
|
||||
manifest = manifestUtil.loadManifest(inputStream, "theme.json");
|
||||
} else if (ccmFiles.existsFile(String.format(THEME_XML,
|
||||
themePath))) {
|
||||
} else if (ccmFiles.existsFile(xmlPath)) {
|
||||
final InputStream inputStream = ccmFiles
|
||||
.createInputStream(xmlPath);
|
||||
manifest = manifestUtil.loadManifest(inputStream, "theme.xml");
|
||||
} else {
|
||||
return Optional.empty();
|
||||
|
|
|
|||
|
|
@ -391,6 +391,11 @@ public class StaticThemeProvider implements ThemeProvider {
|
|||
//No op in this implementation.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unpublishTheme(final String theme) {
|
||||
//No op in this implementation.
|
||||
}
|
||||
|
||||
private URI getJarUri() {
|
||||
|
||||
LOGGER.debug("Getting URI of JAR...");
|
||||
|
|
|
|||
|
|
@ -209,4 +209,13 @@ public interface ThemeProvider extends Serializable {
|
|||
*/
|
||||
void publishTheme(String theme);
|
||||
|
||||
/**
|
||||
* Unpublishes (deletes) the live version of a theme. For
|
||||
* implementations which do not support draft/live themes the implementation
|
||||
* of this method should be a noop, but not throw an exception.
|
||||
*
|
||||
* @param theme The theme to publish.
|
||||
*/
|
||||
void unpublishTheme(String theme);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,6 +326,14 @@ public class DatabaseThemeProvider implements ThemeProvider {
|
|||
.ifPresent(themeManager::publishTheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unpublishTheme(final String themeName) {
|
||||
|
||||
themeRepository
|
||||
.findThemeByName(themeName, ThemeVersion.LIVE)
|
||||
.ifPresent(themeManager::unpublishTheme);
|
||||
}
|
||||
|
||||
private ThemeInfo createThemeInfo(final Theme theme) {
|
||||
|
||||
Objects.requireNonNull(theme);
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ package org.libreccm.theming.manager;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.security.RequiresPrivilege;
|
||||
import org.libreccm.theming.ThemeInfo;
|
||||
import org.libreccm.theming.ThemeProvider;
|
||||
import org.libreccm.theming.ThemeVersion;
|
||||
import org.libreccm.theming.ThemingPrivileges;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
|
|
@ -40,6 +42,7 @@ import javax.json.JsonArrayBuilder;
|
|||
import javax.json.JsonWriter;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
|
@ -49,8 +52,6 @@ import javax.ws.rs.WebApplicationException;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import static javassist.CtClass.*;
|
||||
import static org.reflections.util.Utils.*;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -74,6 +75,8 @@ public class Themes implements Serializable {
|
|||
@GET
|
||||
@Path("/providers")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
//@AuthorizationRequired
|
||||
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
|
||||
public String getThemeProviders() {
|
||||
|
||||
final List<ThemeProvider> providersList = new ArrayList<>();
|
||||
|
|
@ -100,6 +103,8 @@ public class Themes implements Serializable {
|
|||
@GET
|
||||
@Path("/themes")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
//@AuthorizationRequired
|
||||
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
|
||||
public List<ThemeInfo> getAvailableThemes() {
|
||||
|
||||
final List<ThemeInfo> availableThemes = new ArrayList<>();
|
||||
|
|
@ -115,6 +120,8 @@ public class Themes implements Serializable {
|
|||
@GET
|
||||
@Path("/themes/{theme}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
//@AuthorizationRequired
|
||||
@RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
|
||||
public ThemeInfo getTheme(@PathParam("theme") final String themeName) {
|
||||
|
||||
for (final ThemeProvider provider : providers) {
|
||||
|
|
@ -133,6 +140,8 @@ public class Themes implements Serializable {
|
|||
@Path("/themes/{theme}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@SuppressWarnings("unchecked")
|
||||
//@AuthorizationRequired
|
||||
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
|
||||
public ThemeInfo createTheme(
|
||||
@PathParam("theme") final String themeName,
|
||||
@QueryParam("provider") final String providerName) {
|
||||
|
|
@ -167,19 +176,13 @@ public class Themes implements Serializable {
|
|||
|
||||
@DELETE
|
||||
@Path("/themes/{theme}")
|
||||
//@AuthorizationRequired
|
||||
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
|
||||
public void deleteTheme(@PathParam("theme") final String themeName) {
|
||||
|
||||
Objects.requireNonNull(themeName);
|
||||
|
||||
final List<ThemeProvider> providersList = new ArrayList<>();
|
||||
providers
|
||||
.forEach(provider -> providersList.add(provider));
|
||||
|
||||
final Optional<ThemeProvider> provider = providersList
|
||||
.stream()
|
||||
.filter(current -> current.providesTheme(themeName,
|
||||
ThemeVersion.DRAFT))
|
||||
.findAny();
|
||||
final Optional<ThemeProvider> provider = findProvider(themeName);
|
||||
|
||||
if (provider.isPresent()) {
|
||||
|
||||
|
|
@ -190,6 +193,42 @@ public class Themes implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/themes/{theme}/live")
|
||||
//@AuthorizationRequired
|
||||
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
|
||||
public void publishTheme(@PathParam("theme") final String themeName) {
|
||||
|
||||
final Optional<ThemeProvider> provider = findProvider(themeName);
|
||||
|
||||
if (provider.isPresent()) {
|
||||
|
||||
provider.get().publishTheme(themeName);
|
||||
|
||||
} else {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/themes/{theme}/live")
|
||||
//@AuthorizationRequired
|
||||
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
|
||||
public void unPublishTheme(@PathParam("theme") final String themeName) {
|
||||
|
||||
final Optional<ThemeProvider> provider = findProvider(themeName);
|
||||
|
||||
if (provider.isPresent()) {
|
||||
|
||||
provider.get().unpublishTheme(themeName);
|
||||
|
||||
} else {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getProviderName(final ThemeProvider provider) {
|
||||
|
||||
if (provider
|
||||
|
|
@ -207,4 +246,17 @@ public class Themes implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
private Optional<ThemeProvider> findProvider(final String forTheme) {
|
||||
|
||||
final List<ThemeProvider> providersList = new ArrayList<>();
|
||||
providers
|
||||
.forEach(provider -> providersList.add(provider));
|
||||
|
||||
return providersList
|
||||
.stream()
|
||||
.filter(current -> current.providesTheme(forTheme,
|
||||
ThemeVersion.DRAFT))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue