CCM NG: Various things including a new version of the StaticThemeProvider (not finished yet)

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5093 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2017-10-31 19:12:26 +00:00
parent e280aaf0a1
commit d4d524def8
9 changed files with 648 additions and 269 deletions

View File

@ -196,6 +196,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
<dependency> <dependency>
<groupId>org.primefaces</groupId> <groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId> <artifactId>primefaces</artifactId>

View File

@ -55,6 +55,10 @@ public class SitesTab extends LayoutPanel {
final ActionLink addNewSite = new ActionLink(new GlobalizedMessage( final ActionLink addNewSite = new ActionLink(new GlobalizedMessage(
"ui.admin.sites.add_new_site_link", "ui.admin.sites.add_new_site_link",
ADMIN_BUNDLE)); ADMIN_BUNDLE));
addNewSite
.addActionListener(event -> {
showSiteForm(event.getPageState());
});
final BoxPanel right = new BoxPanel(BoxPanel.VERTICAL); final BoxPanel right = new BoxPanel(BoxPanel.VERTICAL);
right.add(addNewSite); right.add(addNewSite);

View File

@ -18,82 +18,181 @@
*/ */
package org.libreccm.theming; package org.libreccm.theming;
import static org.libreccm.theming.ThemeConstants.*;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.libreccm.core.UnexpectedErrorException; import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.theming.manifest.ThemeManifest; import org.libreccm.theming.manifest.ThemeManifest;
import org.libreccm.theming.manifest.ThemeManifestUtil; import org.libreccm.theming.manifest.ThemeManifestUtil;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URI; import java.net.URISyntaxException;
import java.nio.file.FileSystem; import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
* A theme provider implementation which serves themes from the class path
* ({@code /themes)}. This implementation does not support changes to the
* theme(s) and files.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@RequestScoped @RequestScoped
public class StaticThemeProvider implements ThemeProvider { public class StaticThemeProvider implements ThemeProvider {
private static final Logger LOGGER = LogManager private static final long serialVersionUID = 7174370298224448067L;
.getLogger(StaticThemeProvider.class); private static final Logger LOGGER = LogManager.getLogger(
StaticThemeProvider.class);
/**
* Path the the static themes.
*/
private static final String THEMES_DIR = "/themes"; private static final String THEMES_DIR = "/themes";
private static final long serialVersionUID = -8701021965452233811L; private static final String THEME_MANIFEST_JSON = THEMES_DIR
+ "/%s/theme.json";
private static final String THEME_MANIFEST_XML = THEMES_DIR
+ "/%s/theme.xml";
@Inject @Inject
private ThemeFileInfoUtil themeFileInfoUtil; private ThemeManifestUtil manifestUtil;
@Inject
private ThemeManifestUtil themeManifests;
@Override @Override
public List<ThemeInfo> getThemes() { public List<ThemeInfo> getThemes() {
LOGGER.debug("Retrieving info about all static themes..."); final Reflections reflections = new Reflections(
new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("themes"))
.setScanners(new ResourcesScanner()));
final Set<String> resources = reflections
.getResources(Pattern.compile("themes/.*/theme.json"));
LOGGER.debug("Found resources:");
for (final String resource : resources) {
LOGGER.debug("\t{}", resource);
}
try (final FileSystem jarFileSystem = FileSystems.newFileSystem( final URL themesUrl = StaticThemeProvider.class.getResource(THEMES_DIR);
getJarUri(), Collections.emptyMap())) {
final Path themesPath = jarFileSystem.getPath(THEMES_DIR); if (themesUrl == null) {
if (!Files.isDirectory(themesPath)) { throw new UnexpectedErrorException(
LOGGER.warn(THEMES_DIR + " is not a directory. Returning " "Static themes directory does not"
+ "empty list."); + "exist in class path. Something is wrong.");
return Collections.emptyList(); }
File directory;
try {
directory = new File(themesUrl.toURI());
} catch (URISyntaxException ex) {
throw new UnexpectedErrorException(ex);
} catch (IllegalArgumentException ex) {
directory = null;
}
final List<String> themeDirs = new ArrayList<>();
if (directory != null && directory.exists()) {
final String[] files = directory.list();
for (final String file : files) {
themeDirs.add(file);
} }
} else {
final String jarPath = themesUrl
.getFile()
.replaceFirst("[.]jar[!].*", ".jar")
.replaceFirst("file:", "");
return Files final JarFile jarFile;
.list(themesPath) try {
.filter(this::isTheme) jarFile = new JarFile(jarPath);
.map(this::generateThemeInfo) } catch (IOException ex) {
.collect(Collectors.toList()); throw new UnexpectedErrorException(ex);
}
final Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
final JarEntry jarEntry = jarEntries.nextElement();
final String jarEntryName = jarEntry.getName();
if (jarEntryName.startsWith("themes")
&& jarEntryName.length() > "themes/".length()
&& jarEntryName.endsWith("/")) {
themeDirs.add(jarEntryName);
}
}
}
return themeDirs
.stream()
.filter(dirPath -> isThemeDir(dirPath))
.map(dirPath -> loadThemeManifest(dirPath))
.map(manifest -> generateThemeInfo(manifest))
.collect(Collectors.toList());
}
private boolean isThemeDir(final String dirPath) {
Objects.requireNonNull(dirPath);
final URL manifestJsonUrl = StaticThemeProvider.class.getResource(
String.format(THEME_MANIFEST_JSON, dirPath));
final URL manifestXmlUrl = StaticThemeProvider.class.getResource(
String.format(THEME_MANIFEST_XML, dirPath));
return (manifestJsonUrl != null) || (manifestXmlUrl != null);
}
private ThemeManifest loadThemeManifest(final String dirPath) {
Objects.requireNonNull(dirPath);
final URL manifestJsonUrl = StaticThemeProvider.class.getResource(
String.format(THEME_MANIFEST_JSON, dirPath));
final URL manifestXmlUrl = StaticThemeProvider.class.getResource(
String.format(THEME_MANIFEST_XML, dirPath));
final URL manifestUrl;
if (manifestJsonUrl != null) {
manifestUrl = manifestJsonUrl;
} else if (manifestXmlUrl != null) {
manifestUrl = manifestXmlUrl;
} else {
throw new IllegalArgumentException(String
.format("Path \"%s\" does not point to a valid theme manifest.",
dirPath));
}
final ThemeManifest themeManifest;
try (final InputStream inputStream = manifestUrl.openStream()) {
themeManifest = manifestUtil.loadManifest(inputStream,
manifestUrl.toString());
} catch (IOException ex) { } catch (IOException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
return themeManifest;
}
private ThemeInfo generateThemeInfo(final ThemeManifest manifest) {
Objects.requireNonNull(manifest);
final ThemeInfo info = new ThemeInfo();
info.setManifest(manifest);
info.setProvider(getClass());
info.setVersion(ThemeVersion.LIVE);
return info;
} }
@Override @Override
@ -106,31 +205,13 @@ public class StaticThemeProvider implements ThemeProvider {
final ThemeVersion version) { final ThemeVersion version) {
Objects.requireNonNull(theme); Objects.requireNonNull(theme);
Objects.requireNonNull(version);
if (theme.matches("\\s*")) { if (isThemeDir(theme)) {
throw new IllegalArgumentException( return Optional.of(generateThemeInfo(loadThemeManifest(theme)));
"The name of the theme can't be empty."); } else {
return Optional.empty();
} }
LOGGER.debug("Trying to find static theme \"{}\"...",
theme);
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
if (isTheme(themePath)) {
return Optional.of(generateThemeInfo(themePath));
} else {
return Optional.empty();
}
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
} }
@Override @Override
@ -138,30 +219,9 @@ public class StaticThemeProvider implements ThemeProvider {
final ThemeVersion version) { final ThemeVersion version) {
Objects.requireNonNull(theme); Objects.requireNonNull(theme);
Objects.requireNonNull(version);
if (theme.isEmpty() || theme.matches("\\s*")) { return isThemeDir(theme);
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
LOGGER.debug("Determining if there is static theme \"{}\"...",
theme);
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
LOGGER.debug("Is there a static theme \"{}\": {}",
theme,
isTheme(themePath));
return isTheme(themePath);
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
} }
@Override @Override
@ -169,128 +229,19 @@ public class StaticThemeProvider implements ThemeProvider {
final ThemeVersion version, final ThemeVersion version,
final String path) { final String path) {
Objects.requireNonNull(theme); throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
Objects.requireNonNull(version);
Objects.requireNonNull(path);
if (theme.isEmpty() || theme.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
final String pathToDir;
if ("".equals(path)) {
pathToDir = "/";
} else {
pathToDir = path;
}
LOGGER.debug("Listing all files in path \"{]\" of theme \"{}\"...",
path,
theme);
final List<ThemeFileInfo> infos;
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
if (!isTheme(themePath)) {
throw new IllegalArgumentException(String
.format("Theme \"%s\" does not exist.",
theme));
}
final Path dirPath = themePath.resolve(pathToDir);
if (Files.exists(dirPath)) {
if (Files.isDirectory(dirPath)) {
try (final Stream<Path> stream = Files.list(dirPath)) {
infos = stream
.map(themeFileInfoUtil::buildThemeInfo)
.collect(Collectors.toList());
}
} else {
infos = new ArrayList<>();
infos.add(themeFileInfoUtil.buildThemeInfo(dirPath));
}
} else {
throw new IllegalArgumentException(String
.format("No file/directory \"%s\" in theme \"%s\".",
path,
theme));
}
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
LOGGER.debug("Files in path \"{}\" of static theme \"{}\": {}",
pathToDir,
theme,
Objects.toString(infos));
return infos;
} }
@Override @Override
public Optional<InputStream> getThemeFileAsStream(final String theme, public Optional<InputStream> getThemeFileAsStream(String theme,
final ThemeVersion version, ThemeVersion version,
final String path) { String path) {
Objects.requireNonNull(theme); throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
Objects.requireNonNull(version);
Objects.requireNonNull(path);
if (theme.isEmpty() || theme.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
if (path.isEmpty() || path.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
final Path filePath;
if (path.charAt(0) == '/') {
filePath = themePath.resolve(path.substring(1));
} else {
filePath = themePath.resolve(path);
}
if (!Files.isRegularFile(filePath)) {
throw new IllegalArgumentException(String
.format("The provided path \"%s\" in theme \"%s\" points "
+ "not to a regular file.",
path,
theme));
}
if (Files.exists(filePath)) {
return Optional.of(Files.newInputStream(filePath));
} else {
return Optional.empty();
}
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
} }
@Override @Override
public OutputStream getOutputStreamForThemeFile(final String theme, public OutputStream getOutputStreamForThemeFile(String theme, String path) {
final String path) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
throw new UnsupportedOperationException("Not supported by this"
+ " implemetentation");
} }
@Override @Override
@ -305,72 +256,7 @@ public class StaticThemeProvider implements ThemeProvider {
@Override @Override
public void publishTheme(final String theme) { public void publishTheme(final String theme) {
LOGGER.info("StaticThemeProvider#publishTheme(String) called, but " //No op in this implementation.
+ "StaticThemeProvider does not support draft/live "
+ "themes.");
}
private URI getJarUri() {
LOGGER.debug("Getting URI of JAR...");
final String themesUrl = getClass().getResource(THEMES_DIR).toString();
LOGGER.debug("Full URL of " + THEMES_DIR + " directory: {}", themesUrl);
final int index = themesUrl.indexOf('!');
final String pathToJar = themesUrl.substring(0, index);
final URI uri = URI.create(pathToJar);
LOGGER.debug("URI to JAR is \"%s\".", uri.toString());
return uri;
}
private boolean isTheme(final Path path) {
Objects.requireNonNull(path);
if (!Files.isDirectory(path)) {
return false;
}
final Path manifestPathJson = path.resolve(THEME_MANIFEST_JSON);
final Path manifestPathXml = path.resolve(THEME_MANIFEST_XML);
return Files.exists(manifestPathJson) || Files.exists(manifestPathXml);
}
private ThemeInfo generateThemeInfo(final Path path) {
Objects.requireNonNull(path);
if (!Files.exists(path)) {
throw new IllegalArgumentException(String
.format("The provided path \"%s\" does "
+ "not exist.",
path.toString()));
}
final Path manifestPathJson = path.resolve(THEME_MANIFEST_JSON);
final Path manifestPathXml = path.resolve(THEME_MANIFEST_XML);
final ThemeManifest manifest;
if (Files.exists(manifestPathJson)) {
manifest = themeManifests.loadManifest(manifestPathJson);
} else if (Files.exists(manifestPathXml)) {
manifest = themeManifests.loadManifest(manifestPathXml);
} else {
throw new IllegalArgumentException(String
.format("The provided path \"%s\" does "
+ "contain a theme manifest file.",
path.toString()));
}
final ThemeInfo themeInfo = new ThemeInfo();
themeInfo.setVersion(ThemeVersion.LIVE);
themeInfo.setProvider(getClass());
themeInfo.setManifest(manifest);
return themeInfo;
} }
} }

View File

@ -0,0 +1,376 @@
/*
* Copyright (C) 2017 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;
import static org.libreccm.theming.ThemeConstants.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.core.UnexpectedErrorException;
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.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
* A theme provider implementation which serves themes from the class path
* ({@code /themes)}. This implementation does not support changes to the
* theme(s) and files.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class StaticThemeProvider implements ThemeProvider {
private static final Logger LOGGER = LogManager
.getLogger(StaticThemeProvider.class);
/**
* Path the the static themes.
*/
private static final String THEMES_DIR = "/themes";
private static final long serialVersionUID = -8701021965452233811L;
@Inject
private ThemeFileInfoUtil themeFileInfoUtil;
@Inject
private ThemeManifestUtil themeManifests;
@Override
public List<ThemeInfo> getThemes() {
LOGGER.debug("Retrieving info about all static themes...");
try (final FileSystem jarFileSystem = FileSystems.newFileSystem(
getJarUri(), Collections.emptyMap())) {
final Path themesPath = jarFileSystem.getPath(THEMES_DIR);
if (!Files.isDirectory(themesPath)) {
LOGGER.warn(THEMES_DIR + " is not a directory. Returning "
+ "empty list.");
return Collections.emptyList();
}
return Files
.list(themesPath)
.filter(this::isTheme)
.map(this::generateThemeInfo)
.collect(Collectors.toList());
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
}
@Override
public List<ThemeInfo> getLiveThemes() {
return getThemes();
}
@Override
public Optional<ThemeInfo> getThemeInfo(final String theme,
final ThemeVersion version) {
Objects.requireNonNull(theme);
Objects.requireNonNull(version);
if (theme.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
LOGGER.debug("Trying to find static theme \"{}\"...",
theme);
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
if (isTheme(themePath)) {
return Optional.of(generateThemeInfo(themePath));
} else {
return Optional.empty();
}
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
}
@Override
public boolean providesTheme(final String theme,
final ThemeVersion version) {
Objects.requireNonNull(theme);
Objects.requireNonNull(version);
if (theme.isEmpty() || theme.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
LOGGER.debug("Determining if there is static theme \"{}\"...",
theme);
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
LOGGER.debug("Is there a static theme \"{}\": {}",
theme,
isTheme(themePath));
return isTheme(themePath);
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
}
@Override
public List<ThemeFileInfo> listThemeFiles(final String theme,
final ThemeVersion version,
final String path) {
Objects.requireNonNull(theme);
Objects.requireNonNull(version);
Objects.requireNonNull(path);
if (theme.isEmpty() || theme.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
final String pathToDir;
if ("".equals(path)) {
pathToDir = "/";
} else {
pathToDir = path;
}
LOGGER.debug("Listing all files in path \"{]\" of theme \"{}\"...",
path,
theme);
final List<ThemeFileInfo> infos;
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
if (!isTheme(themePath)) {
throw new IllegalArgumentException(String
.format("Theme \"%s\" does not exist.",
theme));
}
final Path dirPath = themePath.resolve(pathToDir);
if (Files.exists(dirPath)) {
if (Files.isDirectory(dirPath)) {
try (final Stream<Path> stream = Files.list(dirPath)) {
infos = stream
.map(themeFileInfoUtil::buildThemeInfo)
.collect(Collectors.toList());
}
} else {
infos = new ArrayList<>();
infos.add(themeFileInfoUtil.buildThemeInfo(dirPath));
}
} else {
throw new IllegalArgumentException(String
.format("No file/directory \"%s\" in theme \"%s\".",
path,
theme));
}
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
LOGGER.debug("Files in path \"{}\" of static theme \"{}\": {}",
pathToDir,
theme,
Objects.toString(infos));
return infos;
}
@Override
public Optional<InputStream> getThemeFileAsStream(final String theme,
final ThemeVersion version,
final String path) {
Objects.requireNonNull(theme);
Objects.requireNonNull(version);
Objects.requireNonNull(path);
if (theme.isEmpty() || theme.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
if (path.isEmpty() || path.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of the theme can't be empty.");
}
try (final FileSystem jarFileSystem = FileSystems
.newFileSystem(getJarUri(), Collections.emptyMap())) {
final Path themePath = jarFileSystem
.getPath(String.format(THEMES_DIR + "/%s", theme));
final Path filePath;
if (path.charAt(0) == '/') {
filePath = themePath.resolve(path.substring(1));
} else {
filePath = themePath.resolve(path);
}
if (!Files.isRegularFile(filePath)) {
throw new IllegalArgumentException(String
.format("The provided path \"%s\" in theme \"%s\" points "
+ "not to a regular file.",
path,
theme));
}
if (Files.exists(filePath)) {
return Optional.of(Files.newInputStream(filePath));
} else {
return Optional.empty();
}
} catch (IOException ex) {
throw new UnexpectedErrorException(ex);
}
}
@Override
public OutputStream getOutputStreamForThemeFile(final String theme,
final String path) {
throw new UnsupportedOperationException("Not supported by this"
+ " implemetentation");
}
@Override
public boolean supportsChanges() {
return false;
}
@Override
public boolean supportsDraftThemes() {
return false;
}
@Override
public void publishTheme(final String theme) {
LOGGER.info("StaticThemeProvider#publishTheme(String) called, but "
+ "StaticThemeProvider does not support draft/live "
+ "themes.");
}
private URI getJarUri() {
LOGGER.debug("Getting URI of JAR...");
final String themesUrl = getClass().getResource(THEMES_DIR).toString();
LOGGER.debug("Full URL of " + THEMES_DIR + " directory: {}", themesUrl);
final int index = themesUrl.indexOf('!');
final String pathToJar = themesUrl.substring(0, index);
final URI uri = URI.create(pathToJar);
LOGGER.debug("URI to JAR is \"%s\".", uri.toString());
return uri;
}
private boolean isTheme(final Path path) {
Objects.requireNonNull(path);
if (!Files.isDirectory(path)) {
return false;
}
final Path manifestPathJson = path.resolve(THEME_MANIFEST_JSON);
final Path manifestPathXml = path.resolve(THEME_MANIFEST_XML);
return Files.exists(manifestPathJson) || Files.exists(manifestPathXml);
}
private ThemeInfo generateThemeInfo(final Path path) {
Objects.requireNonNull(path);
if (!Files.exists(path)) {
throw new IllegalArgumentException(String
.format("The provided path \"%s\" does "
+ "not exist.",
path.toString()));
}
final Path manifestPathJson = path.resolve(THEME_MANIFEST_JSON);
final Path manifestPathXml = path.resolve(THEME_MANIFEST_XML);
final ThemeManifest manifest;
if (Files.exists(manifestPathJson)) {
manifest = themeManifests.loadManifest(manifestPathJson);
} else if (Files.exists(manifestPathXml)) {
manifest = themeManifests.loadManifest(manifestPathXml);
} else {
throw new IllegalArgumentException(String
.format("The provided path \"%s\" does "
+ "contain a theme manifest file.",
path.toString()));
}
final ThemeInfo themeInfo = new ThemeInfo();
themeInfo.setVersion(ThemeVersion.LIVE);
themeInfo.setProvider(getClass());
themeInfo.setManifest(manifest);
return themeInfo;
}
}

View File

@ -28,7 +28,11 @@ import org.libreccm.core.UnexpectedErrorException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable; import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -50,11 +54,12 @@ public class ThemeManifestUtil implements Serializable {
* Reads the manifest file at {@code path}. * Reads the manifest file at {@code path}.
* *
* @param path The path of the manifest file. * @param path The path of the manifest file.
*
* @return The parsed manifest file. * @return The parsed manifest file.
*/ */
public ThemeManifest loadManifest(final Path path) { public ThemeManifest loadManifest(final Path path) {
final String pathStr = path.toString().toLowerCase(Locale.ROOT); // final String pathStr = path.toString().toLowerCase(Locale.ROOT);
final BufferedReader reader; final BufferedReader reader;
try { try {
@ -63,6 +68,72 @@ public class ThemeManifestUtil implements Serializable {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
return parseManifest(reader, path.toString());
// final ObjectMapper mapper;
// if (pathStr.endsWith(THEME_MANIFEST_JSON)) {
// mapper = new ObjectMapper();
// } else if (pathStr.endsWith(THEME_MANIFEST_XML)) {
// final JacksonXmlModule xmlModule = new JacksonXmlModule();
// mapper = new XmlMapper(xmlModule);
// } else {
// throw new IllegalArgumentException(String
// .format("The provided path \"%s\" does not point to a theme "
// + "manifest file.",
// path.toString()));
// }
//
// mapper.registerModule(new JaxbAnnotationModule());
//
// final ThemeManifest manifest;
// try {
// manifest = mapper.readValue(reader, ThemeManifest.class);
// } catch (IOException ex) {
// throw new UnexpectedErrorException(ex);
// }
// return manifest;
}
public ThemeManifest loadManifest(final InputStream inputStream,
final String fileName) {
final InputStreamReader reader;
try {
reader = new InputStreamReader(inputStream, "UTF-8");
} catch (UnsupportedEncodingException ex) {
throw new UnexpectedErrorException(ex);
}
return parseManifest(reader, fileName);
// final ObjectMapper mapper;
// if (fileName.endsWith(THEME_MANIFEST_JSON)) {
// mapper = new ObjectMapper();
// } else if (fileName.endsWith(THEME_MANIFEST_XML)) {
// final JacksonXmlModule xmlModule = new JacksonXmlModule();
// mapper = new XmlMapper(xmlModule);
// } else {
// throw new IllegalArgumentException(String
// .format("The provided path \"%s\" does not point to a theme "
// + "manifest file.",
// fileName));
// }
//
// mapper.registerModule(new JaxbAnnotationModule());
//
// final ThemeManifest manifest;
// try {
// manifest = mapper.readValue(reader, ThemeManifest.class);
// } catch (IOException ex) {
// throw new UnexpectedErrorException(ex);
// }
// return manifest;
}
private ThemeManifest parseManifest(final Reader reader, final String path) {
final String pathStr = path.toLowerCase(Locale.ROOT);
final ObjectMapper mapper; final ObjectMapper mapper;
if (pathStr.endsWith(THEME_MANIFEST_JSON)) { if (pathStr.endsWith(THEME_MANIFEST_JSON)) {
mapper = new ObjectMapper(); mapper = new ObjectMapper();
@ -73,7 +144,7 @@ public class ThemeManifestUtil implements Serializable {
throw new IllegalArgumentException(String throw new IllegalArgumentException(String
.format("The provided path \"%s\" does not point to a theme " .format("The provided path \"%s\" does not point to a theme "
+ "manifest file.", + "manifest file.",
path.toString())); path));
} }
mapper.registerModule(new JaxbAnnotationModule()); mapper.registerModule(new JaxbAnnotationModule());

View File

@ -616,3 +616,12 @@ ui.user.roles.remove=Remove
ui.role.parties.remove=Remove ui.role.parties.remove=Remove
ui.admin.role_edit.description.label=Description ui.admin.role_edit.description.label=Description
ui.admin.tab.sites.title=Sites ui.admin.tab.sites.title=Sites
ui.admin.sites.add_new_site_link=Create new Site
ui.admin.sites.no_sites=No Sites available
ui.admin.sites.table.columns.domain.header=Domain
ui.admin.sites.table.columns.default_site.header=Default Site?
ui.admin.sites.table.columns.default_theme.header=Default theme
ui.admin.sites.table.columns.applications.header=Applications
ui.admin.sites.table.columns.delete.header=Delete
ui.admin.sites.delete.confirm=Are you sure to delete this site?
ui.admin.sites.table.columns.remove.label=Delete

View File

@ -620,3 +620,12 @@ ui.user.roles.remove=Entfernen
ui.role.parties.remove=Entfernen ui.role.parties.remove=Entfernen
ui.admin.role_edit.description.label=Beschreibung ui.admin.role_edit.description.label=Beschreibung
ui.admin.tab.sites.title=Sites ui.admin.tab.sites.title=Sites
ui.admin.sites.add_new_site_link=Neue Site anlegen
ui.admin.sites.no_sites=Keine Sites vorhanden
ui.admin.sites.table.columns.domain.header=Domain
ui.admin.sites.table.columns.default_site.header=Standard Site?
ui.admin.sites.table.columns.default_theme.header=Standard Theme
ui.admin.sites.table.columns.applications.header=Applications
ui.admin.sites.table.columns.delete.header=L\u00f6schen
ui.admin.sites.delete.confirm=Sind Sie sicher, dass Sie diese Site l\u00f6schen wollen?
ui.admin.sites.table.columns.remove.label=L\u00f6schen

View File

@ -613,3 +613,12 @@ ui.user.roles.remove=Remove
ui.role.parties.remove=Remove ui.role.parties.remove=Remove
ui.admin.role_edit.description.label=Description ui.admin.role_edit.description.label=Description
ui.admin.tab.sites.title=Sites ui.admin.tab.sites.title=Sites
ui.admin.sites.add_new_site_link=Create new Site
ui.admin.sites.no_sites=No Sites available
ui.admin.sites.table.columns.domain.header=Domain
ui.admin.sites.table.columns.default_site.header=Default Site?
ui.admin.sites.table.columns.default_theme.header=Default theme
ui.admin.sites.table.columns.applications.header=Applications
ui.admin.sites.table.columns.delete.header=Delete
ui.admin.sites.delete.confirm=Are you sure to delete this site?
ui.admin.sites.table.columns.remove.label=Delete

View File

@ -604,3 +604,12 @@ ui.user.roles.remove=Remove
ui.role.parties.remove=Remove ui.role.parties.remove=Remove
ui.admin.role_edit.description.label=Description ui.admin.role_edit.description.label=Description
ui.admin.tab.sites.title=Sites ui.admin.tab.sites.title=Sites
ui.admin.sites.add_new_site_link=Create new Site
ui.admin.sites.no_sites=No Sites available
ui.admin.sites.table.columns.domain.header=Domain
ui.admin.sites.table.columns.default_site.header=Default Site?
ui.admin.sites.table.columns.default_theme.header=Default theme
ui.admin.sites.table.columns.applications.header=Applications
ui.admin.sites.table.columns.delete.header=Delete
ui.admin.sites.delete.confirm=Are you sure to delete this site?
ui.admin.sites.table.columns.remove.label=Delete