CcM NG: First part for ThemeManager UI
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5691 8810af33-2d31-482b-a856-94f89814c4df
parent
35ebec9d38
commit
4297bbc4cc
|
|
@ -434,14 +434,6 @@ public class NIOFileSystemAdapter implements FileSystemAdapter {
|
|||
throw new InsufficientPermissionsException(path);
|
||||
}
|
||||
|
||||
try {
|
||||
if (Files.isDirectory(nioPath) && Files.list(nioPath).count() > 0) {
|
||||
throw new DirectoryNotEmptyException(path);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new FileAccessException(path, ex);
|
||||
}
|
||||
|
||||
if (recursively && Files.isDirectory(nioPath)) {
|
||||
final List<String> files;
|
||||
try {
|
||||
|
|
@ -455,7 +447,11 @@ public class NIOFileSystemAdapter implements FileSystemAdapter {
|
|||
for (final String file : files) {
|
||||
deleteFile(file, recursively);
|
||||
}
|
||||
|
||||
deleteFile(path);
|
||||
} else {
|
||||
|
||||
|
||||
deleteFile(path);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,15 +22,20 @@ import org.libreccm.core.UnexpectedErrorException;
|
|||
import org.libreccm.files.CcmFiles;
|
||||
import org.libreccm.files.DirectoryNotEmptyException;
|
||||
import org.libreccm.files.FileAccessException;
|
||||
import org.libreccm.files.FileAlreadyExistsException;
|
||||
import org.libreccm.files.FileDoesNotExistException;
|
||||
import org.libreccm.files.InsufficientPermissionsException;
|
||||
import org.libreccm.theming.manifest.ThemeManifest;
|
||||
import org.libreccm.theming.manifest.ThemeManifestUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
|
@ -84,8 +89,8 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
.collect(Collectors.toList());
|
||||
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
@ -96,7 +101,7 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
|
||||
try {
|
||||
if (!ccmFiles.isDirectory(BASE_PATH)
|
||||
|| !ccmFiles.isDirectory(DRAFT_THEMES_PATH)) {
|
||||
|| !ccmFiles.isDirectory(LIVE_THEMES_PATH)) {
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
@ -109,8 +114,8 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
.map(info -> info.get())
|
||||
.collect(Collectors.toList());
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
@ -137,6 +142,86 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeInfo createTheme(final String themeName) {
|
||||
|
||||
Objects.requireNonNull(themeName);
|
||||
|
||||
if (themeName.isEmpty() || themeName.matches("\\s*")) {
|
||||
throw new IllegalArgumentException(
|
||||
"The name of a theme can't be empty.");
|
||||
}
|
||||
|
||||
try {
|
||||
ccmFiles.createDirectory(String.format(DRAFT_THEMES_PATH + "/%s",
|
||||
themeName));
|
||||
} catch (FileAccessException
|
||||
| FileAlreadyExistsException
|
||||
| InsufficientPermissionsException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
final ThemeManifest manifest = new ThemeManifest();
|
||||
manifest.setName(themeName);
|
||||
|
||||
final OutputStream outputStream;
|
||||
try {
|
||||
outputStream = ccmFiles.createOutputStream(
|
||||
String.format(DRAFT_THEMES_PATH + "/%s/"
|
||||
+ ThemeConstants.THEME_MANIFEST_JSON,
|
||||
themeName));
|
||||
} catch (FileAccessException
|
||||
| InsufficientPermissionsException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
try(final OutputStreamWriter writer = new OutputStreamWriter(
|
||||
outputStream, StandardCharsets.UTF_8)) {
|
||||
writer
|
||||
.append(manifestUtil
|
||||
.serializeManifest(manifest,
|
||||
ThemeConstants.THEME_MANIFEST_JSON));
|
||||
writer.flush();
|
||||
} catch (IOException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
return getThemeInfo(themeName, ThemeVersion.DRAFT).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTheme(final String themeName) {
|
||||
|
||||
Objects.requireNonNull(themeName);
|
||||
|
||||
if (themeName.isEmpty() || themeName.matches("\\s*")) {
|
||||
throw new IllegalArgumentException(
|
||||
"The name of a theme can't be empty.");
|
||||
}
|
||||
|
||||
final Optional<ThemeInfo> liveTheme = getLiveThemes()
|
||||
.stream()
|
||||
.filter(theme -> theme.getName().equals(themeName))
|
||||
.findAny();
|
||||
|
||||
if (liveTheme.isPresent()) {
|
||||
throw new IllegalArgumentException(String
|
||||
.format("The theme \"%s\" is live and can't be deleted.",
|
||||
themeName));
|
||||
}
|
||||
|
||||
try {
|
||||
ccmFiles.deleteFile(String.format(DRAFT_THEMES_PATH + "/%s",
|
||||
themeName),
|
||||
true);
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| DirectoryNotEmptyException
|
||||
| InsufficientPermissionsException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ThemeFileInfo> listThemeFiles(final String theme,
|
||||
final ThemeVersion version,
|
||||
|
|
@ -154,8 +239,8 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
.collect(Collectors.toList());
|
||||
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
@ -166,7 +251,7 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
final String theme, final ThemeVersion version, final String path) {
|
||||
|
||||
final String themePath = createThemePath(theme, version);
|
||||
final String filePath = String.join(theme, path, "/");
|
||||
final String filePath = String.join(themePath, path, "/");
|
||||
|
||||
try {
|
||||
if (ccmFiles.existsFile(path)) {
|
||||
|
|
@ -175,8 +260,8 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
return Optional.of(ccmFiles.createInputStream(filePath));
|
||||
}
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
@ -194,7 +279,7 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
return ccmFiles.createOutputStream(filePath);
|
||||
|
||||
} catch (FileAccessException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
@ -209,9 +294,9 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
try {
|
||||
ccmFiles.deleteFile(filePath, true);
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| DirectoryNotEmptyException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| FileDoesNotExistException
|
||||
| DirectoryNotEmptyException
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
@ -242,14 +327,14 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
if (ccmFiles.existsFile(liveThemePath)) {
|
||||
ccmFiles.deleteFile(liveThemePath, true);
|
||||
}
|
||||
|
||||
|
||||
ccmFiles.moveFile(liveThemePathTmp, liveThemePath);
|
||||
} catch (DirectoryNotEmptyException
|
||||
| FileAccessException
|
||||
| FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
throw new UnexpectedErrorException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String createThemePath(final String theme,
|
||||
|
|
@ -258,9 +343,9 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
switch (version) {
|
||||
|
||||
case DRAFT:
|
||||
return String.format(DRAFT_THEMES_PATH, theme);
|
||||
return String.format(DRAFT_THEMES_PATH + "/%s", theme);
|
||||
case LIVE:
|
||||
return String.format(LIVE_THEMES_PATH, theme);
|
||||
return String.format(LIVE_THEMES_PATH + "/%s", theme);
|
||||
default:
|
||||
throw new IllegalArgumentException(String
|
||||
.format("Illegal argument for ThemeVersion \"%s\".",
|
||||
|
|
@ -286,8 +371,8 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
return Optional.empty();
|
||||
}
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
@ -310,8 +395,8 @@ public class FileSystemThemeProvider implements ThemeProvider {
|
|||
|
||||
return fileInfo;
|
||||
} catch (FileAccessException
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
| FileDoesNotExistException
|
||||
| InsufficientPermissionsException ex) {
|
||||
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,6 +254,22 @@ public class StaticThemeProvider implements ThemeProvider {
|
|||
return manifestJsonUrl != null || manifestXmlUrl != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeInfo createTheme(final String theme) {
|
||||
|
||||
throw new UnsupportedOperationException(String.format(
|
||||
"The ThemeProvider %s does support the creation of new themes.",
|
||||
getClass().getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTheme(final String theme) {
|
||||
|
||||
throw new UnsupportedOperationException(String.format(
|
||||
"The ThemeProvider %s does support the deltion of themes.",
|
||||
getClass().getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ThemeFileInfo> listThemeFiles(final String theme,
|
||||
final ThemeVersion version,
|
||||
|
|
|
|||
|
|
@ -79,6 +79,36 @@ public interface ThemeProvider extends Serializable {
|
|||
*/
|
||||
boolean providesTheme(String theme, ThemeVersion version);
|
||||
|
||||
/**
|
||||
* Creates a new theme.
|
||||
*
|
||||
* The theme should be empty besides the manifest file. If a theme with the
|
||||
* provided name already exists implementations should throw an
|
||||
* {@link IllegalArgumentException}.
|
||||
*
|
||||
* {@code ThemeProvider} implementations which do not support the the
|
||||
* creation of new themes the implementation of the method should throw a
|
||||
* {@link UnsupportedOperationException}.
|
||||
*
|
||||
* @param themeName The name of the new theme.
|
||||
*
|
||||
* @return The {@link ThemeInfo} about the new theme.
|
||||
*/
|
||||
ThemeInfo createTheme(String themeName);
|
||||
|
||||
/**
|
||||
* Deletes a theme and all its content.
|
||||
*
|
||||
* If the is live implementations should throw an exception.
|
||||
*
|
||||
* {@code ThemeProvider} implementations which do not support the the
|
||||
* deletion of themes the implementation of the method should throw a
|
||||
* {@link UnsupportedOperationException}.
|
||||
*
|
||||
* @param themeName The theme to delete.
|
||||
*/
|
||||
void deleteTheme(String themeName);
|
||||
|
||||
/**
|
||||
* List all files in a theme at the specified path.
|
||||
*
|
||||
|
|
@ -154,7 +184,7 @@ public interface ThemeProvider extends Serializable {
|
|||
OutputStream getOutputStreamForThemeFile(String theme, String path);
|
||||
|
||||
void deleteThemeFile(String theme, String path);
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the implementation supports changes to the files of the
|
||||
* themes.
|
||||
|
|
|
|||
|
|
@ -184,9 +184,9 @@ public class Themes implements Serializable {
|
|||
return Optional.empty();
|
||||
} else {
|
||||
final Optional<ThemeInfo> masterTheme = getTheme(
|
||||
theme.getManifest().getMasterTheme(),
|
||||
theme.getManifest().getMasterTheme(),
|
||||
theme.getVersion());
|
||||
|
||||
|
||||
if (masterTheme.isPresent()) {
|
||||
return getFileFromTheme(masterTheme.get(), path);
|
||||
} else {
|
||||
|
|
@ -194,21 +194,22 @@ public class Themes implements Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List all files in a theme at the specified path
|
||||
*
|
||||
*
|
||||
* @param theme The theme from which the file is retrieved.
|
||||
* @param path The path of the file relative to the root directory of the
|
||||
* @param path The path of the file relative to the root directory of the
|
||||
* theme.
|
||||
*
|
||||
* @return A list of all files in the provided directory. If there is no
|
||||
* such path in the theme the list is empty. If the path is the path
|
||||
* of a file and not a directory the list should have one element,
|
||||
* the data about the file itself.
|
||||
*/
|
||||
public List<ThemeFileInfo> listThemesFiles(final ThemeInfo theme,
|
||||
final String path) {
|
||||
|
||||
public List<ThemeFileInfo> listThemeFiles(final ThemeInfo theme,
|
||||
final String path) {
|
||||
|
||||
final Instance<? extends ThemeProvider> forTheme = providers.select(
|
||||
theme.getProvider());
|
||||
|
||||
|
|
@ -221,17 +222,17 @@ public class Themes implements Serializable {
|
|||
}
|
||||
|
||||
final ThemeProvider provider = forTheme.get();
|
||||
return provider.listThemeFiles(theme.getName(),
|
||||
theme.getVersion(),
|
||||
return provider.listThemeFiles(theme.getName(),
|
||||
theme.getVersion(),
|
||||
path);
|
||||
}
|
||||
|
||||
public void deleteThemeFile(final ThemeInfo theme,
|
||||
|
||||
public void deleteThemeFile(final ThemeInfo theme,
|
||||
final String path) {
|
||||
|
||||
final Instance<? extends ThemeProvider> forTheme = providers.select(
|
||||
theme.getProvider());
|
||||
|
||||
|
||||
final Instance<? extends ThemeProvider> forTheme = providers
|
||||
.select(theme.getProvider());
|
||||
|
||||
if (forTheme.isUnsatisfied()) {
|
||||
LOGGER.error("ThemeProvider \"{}\" not found.",
|
||||
theme.getProvider().getName());
|
||||
|
|
@ -242,7 +243,7 @@ public class Themes implements Serializable {
|
|||
|
||||
final ThemeProvider provider = forTheme.get();
|
||||
provider.deleteThemeFile(theme.getName(), path);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,39 @@ public class DatabaseThemeProvider implements ThemeProvider {
|
|||
.isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeInfo createTheme(final String themeName) {
|
||||
|
||||
Objects.requireNonNull(themeName);
|
||||
|
||||
if (themeName.isEmpty() || themeName.matches("\\s*")) {
|
||||
throw new IllegalArgumentException(
|
||||
"The name of a theme can't be empty.");
|
||||
}
|
||||
|
||||
final Theme theme = themeManager.createTheme(themeName);
|
||||
|
||||
return createThemeInfo(theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTheme(final String themeName) {
|
||||
|
||||
Objects.requireNonNull(themeName);
|
||||
|
||||
if (themeName.isEmpty() || themeName.matches("\\s*")) {
|
||||
throw new IllegalArgumentException(
|
||||
"The name of a theme can't be empty.");
|
||||
}
|
||||
|
||||
final Theme theme = themeRepository
|
||||
.findThemeByName(themeName, ThemeVersion.DRAFT)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No theme with name \"%s\" is managed by this provider.",
|
||||
themeName)));
|
||||
themeManager.deleteTheme(theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ThemeFileInfo> listThemeFiles(final String themeName,
|
||||
final ThemeVersion version,
|
||||
|
|
@ -247,7 +280,7 @@ public class DatabaseThemeProvider implements ThemeProvider {
|
|||
|
||||
@Override
|
||||
public void deleteThemeFile(final String themeName, final String path) {
|
||||
|
||||
|
||||
Objects.requireNonNull(themeName);
|
||||
Objects.requireNonNull(path);
|
||||
|
||||
|
|
@ -267,10 +300,10 @@ public class DatabaseThemeProvider implements ThemeProvider {
|
|||
final ThemeFile file = fileRepository
|
||||
.findByPath(theme, path, ThemeVersion.DRAFT)
|
||||
.orElse(createDataFile(theme, path));
|
||||
|
||||
|
||||
if (file instanceof DataFile) {
|
||||
fileManager.delete(file);
|
||||
} else if(file instanceof Directory) {
|
||||
} else if (file instanceof Directory) {
|
||||
fileManager.deleteRecursive(file);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2018 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.libreccm.theming.manager;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.core.Application;
|
||||
|
||||
/**
|
||||
* JAX-RS application for managing themes.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ApplicationPath("/thememanager")
|
||||
public class ThemeManager extends Application {
|
||||
|
||||
@Override
|
||||
public Set<Class<?>> getClasses() {
|
||||
|
||||
final Set<Class<?>> classes = new HashSet<>();
|
||||
classes.add(Themes.class);
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright (C) 2018 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.libreccm.theming.manager;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.theming.ThemeInfo;
|
||||
import org.libreccm.theming.ThemeProvider;
|
||||
import org.libreccm.theming.ThemeVersion;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.enterprise.inject.Any;
|
||||
import javax.enterprise.inject.Instance;
|
||||
import javax.inject.Inject;
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonArrayBuilder;
|
||||
import javax.json.JsonWriter;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
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.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import static javassist.CtClass.*;
|
||||
import static org.reflections.util.Utils.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Path("/")
|
||||
public class Themes implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(Themes.class);
|
||||
|
||||
@Inject
|
||||
@Any
|
||||
private Instance<ThemeProvider> providers;
|
||||
|
||||
@Inject
|
||||
private Themes themes;
|
||||
|
||||
@GET
|
||||
@Path("/providers")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public String getThemeProviders() {
|
||||
|
||||
final List<ThemeProvider> providersList = new ArrayList<>();
|
||||
providers
|
||||
.forEach(provider -> providersList.add(provider));
|
||||
|
||||
final JsonArrayBuilder jsonArrayBuilder = Json.createArrayBuilder();
|
||||
|
||||
providersList
|
||||
.stream()
|
||||
.filter(provider -> provider.supportsChanges()
|
||||
&& provider.supportsDraftThemes())
|
||||
.map(this::getProviderName)
|
||||
.forEach(jsonArrayBuilder::add);
|
||||
|
||||
final StringWriter writer = new StringWriter();
|
||||
final JsonWriter jsonWriter = Json.createWriter(writer);
|
||||
|
||||
jsonWriter.writeArray(jsonArrayBuilder.build());
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/themes")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<ThemeInfo> getAvailableThemes() {
|
||||
|
||||
final List<ThemeInfo> availableThemes = new ArrayList<>();
|
||||
for (final ThemeProvider provider : providers) {
|
||||
if (provider.supportsChanges() && provider.supportsDraftThemes()) {
|
||||
availableThemes.addAll(provider.getThemes());
|
||||
}
|
||||
}
|
||||
|
||||
return availableThemes;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/themes/{theme}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public ThemeInfo getTheme(@PathParam("theme") final String themeName) {
|
||||
|
||||
for (final ThemeProvider provider : providers) {
|
||||
if (provider.providesTheme(themeName, ThemeVersion.DRAFT)) {
|
||||
return provider
|
||||
.getThemeInfo(themeName, ThemeVersion.DRAFT)
|
||||
.orElseThrow(() -> new WebApplicationException(
|
||||
Response.Status.NOT_FOUND));
|
||||
}
|
||||
}
|
||||
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/themes/{theme}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@SuppressWarnings("unchecked")
|
||||
public ThemeInfo createTheme(
|
||||
@PathParam("theme") final String themeName,
|
||||
@QueryParam("provider") final String providerName) {
|
||||
|
||||
Objects.requireNonNull(themeName);
|
||||
Objects.requireNonNull(providerName);
|
||||
|
||||
if (themeName.isEmpty() || themeName.matches("\\s*")) {
|
||||
throw new WebApplicationException("No name for new theme provided.",
|
||||
Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if (providerName.isEmpty() || providerName.matches("\\s*")) {
|
||||
throw new WebApplicationException(
|
||||
"No provider for new theme provided.",
|
||||
Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
final Class<ThemeProvider> providerClass;
|
||||
try {
|
||||
providerClass = (Class<ThemeProvider>) Class.forName(providerName);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new WebApplicationException(
|
||||
String.format("No provider with name \"%s\" available.",
|
||||
providerName),
|
||||
Response.Status.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
final ThemeProvider provider = providers.select(providerClass).get();
|
||||
|
||||
return provider.createTheme(themeName);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/themes/{theme}")
|
||||
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();
|
||||
|
||||
if (provider.isPresent()) {
|
||||
|
||||
provider.get().deleteTheme(themeName);
|
||||
|
||||
} else {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
private String getProviderName(final ThemeProvider provider) {
|
||||
|
||||
if (provider
|
||||
.getClass()
|
||||
.getCanonicalName()
|
||||
.toLowerCase()
|
||||
.contains("$proxy")) {
|
||||
|
||||
final String name = provider.getClass().getCanonicalName();
|
||||
return name.substring(0, name.toLowerCase().indexOf("$proxy"));
|
||||
|
||||
} else {
|
||||
return provider.getClass().getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ package org.libreccm.theming.manifest;
|
|||
import static org.libreccm.theming.ThemeConstants.*;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
|
||||
|
|
@ -149,6 +150,7 @@ public class ThemeManifestUtil implements Serializable {
|
|||
}
|
||||
|
||||
mapper.registerModule(new JaxbAnnotationModule());
|
||||
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
|
||||
final StringWriter writer = new StringWriter();
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public class ThemeFiles {
|
|||
"No theme with name \"%s\" exists.",
|
||||
theme)));
|
||||
|
||||
final List<ThemeFileInfo> fileInfos = themes.listThemesFiles(themeInfo,
|
||||
final List<ThemeFileInfo> fileInfos = themes.listThemeFiles(themeInfo,
|
||||
path);
|
||||
final MultiStatus result;
|
||||
if (fileInfos.isEmpty()) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue