Merge pull request 'Fixed some bugs in the DbThemeProvider' (#12) from fix-dbtheme-bugs into master

Reviewed-on: #12
pull/20/head
jensp 2022-01-05 19:49:30 +01:00
commit 45511c281d
3 changed files with 145 additions and 97 deletions

View File

@ -75,7 +75,7 @@ public class DatabaseThemeProvider implements ThemeProvider {
public String getName() {
return "DatabaseThemeProvider";
}
@Override
public String getClassName() {
return DatabaseThemeProvider.class.getName();
@ -84,7 +84,6 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
@Transactional(Transactional.TxType.REQUIRED)
public List<ThemeInfo> getThemes() {
return themeRepository
.findAll(ThemeVersion.DRAFT)
.stream()
@ -95,7 +94,6 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
public List<ThemeInfo> getLiveThemes() {
return themeRepository
.findAll(ThemeVersion.LIVE)
.stream()
@ -105,18 +103,18 @@ public class DatabaseThemeProvider implements ThemeProvider {
}
@Override
public Optional<ThemeInfo> getThemeInfo(final String themeName,
final ThemeVersion version) {
public Optional<ThemeInfo> getThemeInfo(
final String themeName, final ThemeVersion version
) {
return themeRepository
.findThemeByName(themeName, version)
.map(this::createThemeInfo);
}
@Override
public boolean providesTheme(final String theme,
final ThemeVersion version) {
public boolean providesTheme(
final String theme, final ThemeVersion version
) {
return themeRepository
.findThemeByName(theme, version)
.isPresent();
@ -124,12 +122,12 @@ public class DatabaseThemeProvider 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.");
"The name of a theme can't be empty."
);
}
final Theme theme = themeManager.createTheme(themeName);
@ -139,7 +137,6 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
public void deleteTheme(final String themeName) {
Objects.requireNonNull(themeName);
if (themeName.isEmpty() || themeName.matches("\\s*")) {
@ -149,33 +146,38 @@ public class DatabaseThemeProvider implements ThemeProvider {
final Theme theme = themeRepository
.findThemeByName(themeName, ThemeVersion.DRAFT)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No theme with name \"%s\" is managed by this provider.",
themeName)));
.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,
final String path) {
public List<ThemeFileInfo> listThemeFiles(
final String themeName, final ThemeVersion version, final String path
) {
final Theme theme = themeRepository
.findThemeByName(path, version)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No Theme \"%s\" in the database.", themeName)));
.orElseThrow(
() -> new IllegalArgumentException(
String.format("No Theme \"%s\" in the database.", themeName)
)
);
final Optional<ThemeFile> themeFile = fileRepository
.findByPath(theme, path, version);
final Optional<ThemeFile> themeFile = fileRepository.findByPath(
theme, path, version
);
final List<ThemeFileInfo> result = new ArrayList<>();
if (themeFile.isPresent()) {
if (themeFile.get() instanceof DataFile) {
result.add(themeFile.map(this::createThemeFileInfo).get());
} else if (themeFile.get() instanceof Directory) {
final Directory directory = (Directory) themeFile.get();
result.addAll(directory
.getFiles()
@ -183,9 +185,12 @@ public class DatabaseThemeProvider implements ThemeProvider {
.map(this::createThemeFileInfo)
.collect(Collectors.toList()));
} else {
throw new IllegalArgumentException(String
.format("Unknown type \"%s\".",
themeFile.get().getClass().getName()));
throw new IllegalArgumentException(
String.format(
"Unknown type \"%s\".",
themeFile.get().getClass().getName()
)
);
}
}
@ -194,15 +199,16 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
public Optional<ThemeFileInfo> getThemeFileInfo(
final String themeName, final ThemeVersion version, final String path) {
final String themeName, final ThemeVersion version, final String path
) {
final Theme theme = themeRepository
.findThemeByName(path, version)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No Theme \"%s\" in the database.", themeName)));
final Optional<ThemeFile> themeFile = fileRepository
.findByPath(theme, path, version);
final Optional<ThemeFile> themeFile = fileRepository.findByPath(
theme, path, version
);
if (themeFile.isPresent()) {
return Optional.of(createThemeFileInfo(themeFile.get()));
@ -214,8 +220,8 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
@Transactional(Transactional.TxType.REQUIRED)
public Optional<InputStream> getThemeFileAsStream(
final String themeName, final ThemeVersion version, final String path) {
final String themeName, final ThemeVersion version, final String path
) {
final Optional<Theme> theme = themeRepository
.findThemeByName(themeName, version);
@ -224,11 +230,11 @@ public class DatabaseThemeProvider implements ThemeProvider {
.findByPath(theme.get(), path, version);
if (file.isPresent()) {
if (file.get() instanceof DataFile) {
final DataFile dataFile = (DataFile) file.get();
final byte[] data = Arrays
.copyOf(dataFile.getData(), dataFile.getData().length);
final byte[] data = Arrays.copyOf(
dataFile.getData(), dataFile.getData().length
);
return Optional.of(new ByteArrayInputStream(data));
} else {
@ -244,9 +250,9 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
@Transactional(Transactional.TxType.REQUIRED)
public OutputStream getOutputStreamForThemeFile(final String themeName,
final String path) {
public OutputStream getOutputStreamForThemeFile(
final String themeName, final String path
) {
Objects.requireNonNull(themeName);
Objects.requireNonNull(path);
@ -260,8 +266,11 @@ public class DatabaseThemeProvider implements ThemeProvider {
final Theme theme = themeRepository
.findThemeByName(path, ThemeVersion.DRAFT)
.orElseThrow(() -> new IllegalArgumentException(String
.format("Theme \"%s\" does not exist.", themeName)));
.orElseThrow(
() -> new IllegalArgumentException(
String.format("Theme \"%s\" does not exist.", themeName)
)
);
final ThemeFile file = fileRepository
.findByPath(theme, path, ThemeVersion.DRAFT)
@ -270,15 +279,18 @@ public class DatabaseThemeProvider implements ThemeProvider {
if (file instanceof DataFile) {
return new DataFileOutputStream((DataFile) file);
} else {
throw new IllegalArgumentException(String
.format("The path \"%s\" does not point to a DataFile.",
path));
throw new IllegalArgumentException(
String.format(
"The path \"%s\" does not point to a DataFile.",
path
)
);
}
}
private DataFile createDataFile(final Theme theme,
final String path) {
private DataFile createDataFile(
final Theme theme, final String path
) {
final int lastSlashIndex = path.lastIndexOf('/');
final String parentPath = path.substring(0, lastSlashIndex);
@ -287,12 +299,16 @@ public class DatabaseThemeProvider implements ThemeProvider {
"Path \"%s\" does not point to a file.", path));
}
final ThemeFile parent = fileRepository.findByPath(theme,
path,
ThemeVersion.DRAFT)
.orElseThrow(() -> new IllegalArgumentException(String
.format("The path \"%s\" does not point to a directory.",
path)));
final ThemeFile parent = fileRepository
.findByPath(theme, path, ThemeVersion.DRAFT)
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"The path \"%s\" does not point to a directory.",
path
)
)
);
if (parent instanceof Directory) {
final Directory parentDirectory = (Directory) parent;
@ -308,7 +324,6 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
public void deleteThemeFile(final String themeName, final String path) {
Objects.requireNonNull(themeName);
Objects.requireNonNull(path);
@ -348,7 +363,6 @@ public class DatabaseThemeProvider implements ThemeProvider {
@Override
public void publishTheme(final String themeName) {
themeRepository
.findThemeByName(themeName, ThemeVersion.DRAFT)
.ifPresent(themeManager::publishTheme);
@ -363,15 +377,16 @@ public class DatabaseThemeProvider implements ThemeProvider {
}
private ThemeInfo createThemeInfo(final Theme theme) {
Objects.requireNonNull(theme);
final Optional<ThemeFile> manifestFileJson = fileRepository
.findByNameAndParent(ThemeConstants.THEME_MANIFEST_JSON,
theme.getRootDirectory());
.findByNameAndParent(
ThemeConstants.THEME_MANIFEST_JSON, theme.getRootDirectory()
);
final Optional<ThemeFile> manifestFileXml = fileRepository
.findByNameAndParent(ThemeConstants.THEME_MANIFEST_XML,
theme.getRootDirectory());
.findByNameAndParent(
ThemeConstants.THEME_MANIFEST_XML, theme.getRootDirectory()
);
final DataFile manifestFile;
final String filename;
@ -382,9 +397,11 @@ public class DatabaseThemeProvider implements ThemeProvider {
manifestFile = (DataFile) manifestFileXml.get();
filename = ThemeConstants.THEME_MANIFEST_XML;
} else {
throw new IllegalArgumentException(String
.format("No manifest file found for theme \"%s\".",
theme.getName()));
throw new IllegalArgumentException(
String.format(
"No manifest file found for theme \"%s\".", theme.getName()
)
);
}
try (final InputStream inputStream = new ByteArrayInputStream(
@ -393,7 +410,7 @@ public class DatabaseThemeProvider implements ThemeProvider {
.loadManifest(inputStream, filename);
final ThemeInfo themeInfo = new ThemeInfo();
themeInfo.setManifest(manifest);
themeInfo.setProvider(getClass());
themeInfo.setProvider(DatabaseThemeProvider.class);
themeInfo.setVersion(theme.getVersion());
return themeInfo;
@ -403,7 +420,6 @@ public class DatabaseThemeProvider implements ThemeProvider {
}
private ThemeFileInfo createThemeFileInfo(final ThemeFile file) {
final ThemeFileInfo fileInfo = new ThemeFileInfo();
fileInfo.setName(file.getName());

View File

@ -23,6 +23,7 @@ import org.libreccm.core.CoreConstants;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
@ -31,7 +32,7 @@ import javax.persistence.Table;
/**
* Directory in the file structure of a theme stored in the database.
*
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@ -39,24 +40,42 @@ import javax.persistence.Table;
public class Directory extends ThemeFile {
private static final long serialVersionUID = 3553722448470575337L;
@OneToMany(mappedBy = "parent")
@OrderBy("name ASC")
private List<ThemeFile> files;
public Directory() {
super();
files = new ArrayList<>();
}
public List<ThemeFile> getFiles() {
return Collections.unmodifiableList(files);
return Optional
.ofNullable(files)
.map(Collections::unmodifiableList)
.orElse(Collections.emptyList());
}
protected void setFiles(final List<ThemeFile> files) {
this.files = new ArrayList<>(files);
if (files == null) {
this.files = null;
} else {
this.files = new ArrayList<>(files);
}
}
protected void addFile(final ThemeFile file) {
if (files == null) {
files = new ArrayList<>();
}
files.add(file);
}
protected void removeFile(final ThemeFile file) {
if (files == null) {
return;
}
files.remove(file);
}
@ -84,10 +103,10 @@ public class Directory extends ThemeFile {
final Directory other = (Directory) obj;
return other.canEqual(this);
}
@Override
public boolean canEqual(final Object other) {
return other instanceof Directory;
}
}

View File

@ -78,18 +78,24 @@ public class ThemeManager {
root.setName(name);
root.setPath("/");
root.setTheme(theme);
theme.setRootDirectory(root);
final ThemeManifest manifest = new ThemeManifest();
manifest.setName(name);
final DataFile manifestFile = new DataFile();
manifestFile.setName(ThemeConstants.THEME_MANIFEST_JSON);
manifestFile.setPath(String.format("/%s",
ThemeConstants.THEME_MANIFEST_JSON));
manifestFile.setPath(
String.format(
"/%s", ThemeConstants.THEME_MANIFEST_JSON
)
);
manifestFile.setTheme(theme);
manifestFile.setParent(root);
final String manifestData = manifestUtil
.serializeManifest(manifest, ThemeConstants.THEME_MANIFEST_JSON);
final String manifestData = manifestUtil.serializeManifest(
manifest, ThemeConstants.THEME_MANIFEST_JSON
);
manifestFile.setData(manifestData.getBytes());
root.addFile(manifestFile);
@ -112,9 +118,12 @@ public class ThemeManager {
Objects.requireNonNull(theme);
if (isLive(theme)) {
throw new IllegalArgumentException(String
.format("The theme \"%s\" is live and can't be deleted.",
theme.getName()));
throw new IllegalArgumentException(
String.format(
"The theme \"%s\" is live and can't be deleted.",
theme.getName()
)
);
}
themeRepository.delete(theme);
@ -148,9 +157,14 @@ public class ThemeManager {
} else {
return themeRepository
.findThemeByUuid(theme.getUuid(), ThemeVersion.DRAFT)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No draft theme with UUID \"%s\" in the database.",
theme.getUuid())));
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No draft theme with UUID \"%s\" in the database.",
theme.getUuid()
)
)
);
}
}
@ -166,7 +180,6 @@ public class ThemeManager {
*/
@Transactional(Transactional.TxType.REQUIRED)
public Optional<Theme> getLiveTheme(final Theme theme) {
Objects.requireNonNull(theme);
return themeRepository
@ -185,7 +198,6 @@ public class ThemeManager {
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
@Transactional(Transactional.TxType.REQUIRED)
public void publishTheme(final Theme theme) {
Objects.requireNonNull(theme);
final Theme draftTheme;
@ -222,10 +234,11 @@ public class ThemeManager {
throw new UnsupportedOperationException();
}
private void publishFile(final Theme liveTheme,
final Directory liveParent,
final ThemeFile draftFile) {
private void publishFile(
final Theme liveTheme,
final Directory liveParent,
final ThemeFile draftFile
) {
Objects.requireNonNull(liveParent);
Objects.requireNonNull(draftFile);
@ -238,7 +251,6 @@ public class ThemeManager {
}
if (draftFile instanceof Directory) {
final Directory draftDirectory = (Directory) draftFile;
final Directory liveDirectory = new Directory();
@ -256,7 +268,6 @@ public class ThemeManager {
.forEach(file -> publishFile(liveTheme, liveDirectory, file));
} else if (draftFile instanceof DataFile) {
final DataFile draftDataFile = (DataFile) draftFile;
final DataFile liveDataFile = new DataFile();
@ -289,7 +300,6 @@ public class ThemeManager {
@RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
@Transactional(Transactional.TxType.REQUIRED)
public void unpublishTheme(final Theme theme) {
Objects.requireNonNull(theme);
if (!isLive(theme)) {
@ -321,9 +331,12 @@ public class ThemeManager {
.forEach(file -> unpublishFile(file));
themeFileRepository.delete(themeFile);
} else {
throw new IllegalArgumentException(String
.format("Don't know how handle file type \"%s\".",
themeFile.getClass().getName()));
throw new IllegalArgumentException(
String.format(
"Don't know how handle file type \"%s\".",
themeFile.getClass().getName()
)
);
}
}