diff --git a/ccm-core/src/main/java/org/libreccm/theming/ThemingPrivileges.java b/ccm-core/src/main/java/org/libreccm/theming/ThemingPrivileges.java
new file mode 100644
index 000000000..7d8db9ed0
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/theming/ThemingPrivileges.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+/**
+ * Constants for the privileges which allow actions on themes.
+ *
+ * @author Jens Pelzetter
+ */
+public final class ThemingPrivileges {
+
+ /**
+ * Allows a user to create, delete and publish themes.
+ */
+ public static final String ADMINISTER_THEMES = "administer_themes";
+
+ /**
+ * Allows a user to edit the files of a theme.
+ */
+ public static final String EDIT_THEME = "edit_theme";
+
+ /**
+ * Allows a user to view draft themes.
+ */
+ public static final String PREVIEW_THEME = "preview_theme";
+}
diff --git a/ccm-core/src/main/java/org/libreccm/theming/db/ThemeFileManager.java b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeFileManager.java
new file mode 100644
index 000000000..c72e7dbc2
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeFileManager.java
@@ -0,0 +1,183 @@
+/*
+ * 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.db;
+
+import org.libreccm.security.RequiresPrivilege;
+import org.libreccm.theming.ThemingPrivileges;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+
+/**
+ * Provides methods for managing the files of the theme stored in the database.
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class ThemeFileManager {
+
+ @Inject
+ private ThemeFileRepository fileRepository;
+
+ /**
+ * Creates a new {@link DataFile}.
+ *
+ * @param parent The directory in which the {@link DataFile} is created.
+ * @param name The name of the new {@link DataFile}.
+ *
+ * @return The new {@link DataFile}.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public DataFile createDataFile(final Directory parent,
+ final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new {@link Directory}.
+ *
+ * @param parent The parent directory of the new {@link Directory}.
+ * @param name The name of the new {@link Directory}
+ *
+ * @return The new {@link Directory}.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public Directory createDirectory(final Directory parent,
+ final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Deletes a {@link ThemeFile} in the theme. If the file is a directory the
+ * directory must be empty.
+ *
+ * @param file The {@link ThemeFile} to delete.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public void delete(final ThemeFile file) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Deletes a {@link ThemeFile} recursivly. If the file is a {@link DataFile}
+ * the behaviour is identical to
+ * {@link #delete(org.libreccm.theming.db.ThemeFile)}. If the the file is a
+ * directory all files in the directory and its subdirectories are also
+ * deleted.
+ *
+ * @param file The {@link ThemeFile} to delete.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public void deleteRecursive(final ThemeFile file) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a copy of the {@link ThemeFile}. If the file is a directory an
+ * empty directory is created.
+ *
+ * @param file The file to copy.
+ * @param target The target directory.
+ *
+ * @return The newly created copy.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public ThemeFile copy(final ThemeFile file, final Directory target) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Copies a {@link ThemeFile} and changes its name.
+ *
+ * @param file The file the copy.
+ * @param target The target directory.
+ * @param nameOfCopy The name of the copy.
+ *
+ * @return The copy.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public ThemeFile copy(final ThemeFile file,
+ final Directory target,
+ final String nameOfCopy) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Copies a {@link ThemeFile}. If the file is a directory all files and
+ * subdirectories are also copied.
+ *
+ * @param file The file to copy.
+ * @param target The target directory.
+ *
+ * @return The copy.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public ThemeFile copyRecursive(final ThemeFile file,
+ final Directory target) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Copies a {@link ThemeFile} and sets the name of copy. If the file is a
+ * directory all files and subdirectories are also copied.
+ *
+ * @param file The file to copy.
+ * @param target The target directory.
+ * @param nameOfCopy The name of the copy.
+ *
+ * @return The copy.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public ThemeFile copyRecursive(final ThemeFile file,
+ final Directory target,
+ final String nameOfCopy) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Moves a {@link ThemeFile}.
+ *
+ * @param file The file to move.
+ * @param target The target directory.
+ *
+ * @return The moved file.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public ThemeFile move(final ThemeFile file,
+ final Directory target) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Moves a {@link ThemeFile} and changes its name.
+ *
+ * @param file The file to move.
+ * @param target The target directory.
+ * @param newName The new name of the file.
+ *
+ * @return The moved file.
+ */
+ @RequiresPrivilege(ThemingPrivileges.EDIT_THEME)
+ public ThemeFile move(final ThemeFile file,
+ final Directory target,
+ final String newName) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/theming/db/ThemeFileRepository.java b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeFileRepository.java
index ac66d303b..c099cf5a2 100644
--- a/ccm-core/src/main/java/org/libreccm/theming/db/ThemeFileRepository.java
+++ b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeFileRepository.java
@@ -22,6 +22,7 @@ import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
+import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
@@ -29,6 +30,7 @@ import javax.persistence.TypedQuery;
*
* @author Jens Pelzetter
*/
+@RequestScoped
public class ThemeFileRepository extends AbstractEntityRepository {
private static final long serialVersionUID = -490998638396765429L;
diff --git a/ccm-core/src/main/java/org/libreccm/theming/db/ThemeManager.java b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeManager.java
new file mode 100644
index 000000000..003d27008
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeManager.java
@@ -0,0 +1,88 @@
+/*
+ * 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.db;
+
+import org.libreccm.security.RequiresPrivilege;
+import org.libreccm.theming.ThemingPrivileges;
+import org.libreccm.theming.manifest.ThemeManifest;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+
+/**
+ * Provides methods for managing themes stored in the database.
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class ThemeManager {
+
+ @Inject
+ private ThemeRepository themeRepository;
+
+ /**
+ * Creates a new theme, including the root directory and a theme manifest
+ * file.
+ *
+ * @see ThemeManifest
+ *
+ * @param name The name of the theme.
+ *
+ * @return The new theme.
+ */
+ @RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
+ public Theme createTheme(final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Deletes a theme. The theme must be published.
+ *
+ * @param theme The theme to delete.
+ */
+ @RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
+ public void deleteTheme(final Theme theme) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Publishes a theme. This method will delete the current live version of
+ * the theme (if there is a live version) and create a new live version by
+ * copying all files from the draft version.
+ *
+ * @param theme The theme to publish. If the live version of a theme is
+ * passed here the method will lookup the draft version first.
+ *
+ */
+ @RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
+ public void publishTheme(final Theme theme) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Unpublishes a theme by deleting the live version of the theme.
+ *
+ * @param theme The theme to unpublish.
+ */
+ @RequiresPrivilege(ThemingPrivileges.ADMINISTER_THEMES)
+ public void unpublishTheme(final Theme theme) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/theming/db/ThemeRepository.java b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeRepository.java
index e8d296e9b..4c4bc9ddf 100644
--- a/ccm-core/src/main/java/org/libreccm/theming/db/ThemeRepository.java
+++ b/ccm-core/src/main/java/org/libreccm/theming/db/ThemeRepository.java
@@ -22,6 +22,7 @@ import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
+import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
@@ -30,6 +31,7 @@ import javax.transaction.Transactional;
*
* @author Jens Pelzetter
*/
+@RequestScoped
public class ThemeRepository extends AbstractEntityRepository {
private static final long serialVersionUID = 2243313600794241908L;