diff --git a/ccm-cms/src/main/java/org/librecms/assets/AssetManager.java b/ccm-cms/src/main/java/org/librecms/assets/AssetManager.java
new file mode 100644
index 000000000..f6078dd31
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/assets/AssetManager.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2016 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.librecms.assets;
+
+import java.util.List;
+import java.util.Optional;
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.transaction.Transactional;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.libreccm.categorization.CategoryManager;
+import org.libreccm.core.CoreConstants;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.RequiresPrivilege;
+import org.librecms.CmsConstants;
+import org.librecms.attachments.AttachmentList;
+import org.librecms.contentsection.ContentSection;
+import org.librecms.contentsection.Folder;
+import org.librecms.contentsection.FolderManager;
+import org.librecms.contentsection.FolderRepository;
+
+/**
+ * Provides methods for managing {@link Asset}s, especially sharable
+ * {@link Asset}.
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class AssetManager {
+
+ private static final Logger LOGGER = LogManager.
+ getLogger(AssetManager.class);
+
+ @Inject
+ private EntityManager entityManager;
+
+ @Inject
+ private AssetRepository assetRepo;
+
+ @Inject
+ private CategoryManager categoryManager;
+
+ @Inject
+ private FolderRepository folderRepo;
+
+ @Inject
+ private FolderManager folderManager;
+
+ /**
+ * Creates a new, non shared {@link Asset} and adds it to the provided
+ * {@link AttachmentList}.
+ *
+ * @param Type variable for the type of the new {@link Asset}.
+ * @param name The name of the new {@link Asset}.
+ * @param attachments The {@link AttachmentList} to which the new
+ * {@link Asset} is added.
+ * @param type The type of the new {@link Asset}. Must be a subclass of the
+ * {@link Asset} class.
+ * @return The new {@link Asset}.
+ */
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public T createAsset(
+ final String name,
+ @RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_EDIT)
+ final AttachmentList attachments,
+ final Class type) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Creates a new shared {@link Asset} in the provided {@link Folder}.
+ *
+ * The folder must be a subfolder {@link ContentSection#rootAssetsFolder} of
+ * a content section. Otherwise an {@link IllegalArgumentException} is
+ * thrown.
+ *
+ * @param Type variable for the type of the {@link Asset} to create.
+ * @param name The name of the new {@link Asset}.
+ * @param folder The {@link Folder} in which the {@link Asset} is created.
+ * @param type The type of the new {@link Asset}. Must be a subclass of the
+ * {@link Asset} class.
+ * @return The new {@link Asset}.
+ */
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public T createAsset(
+ final String name,
+ @RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_CREATE_NEW)
+ final Folder folder,
+ final Class type) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Creates a new {@link Asset}. If a folder is provided a sharable
+ * {@link Asset} is created. Otherwise a non shared asset is created. This
+ * method implements the common logic for
+ * {@link #createAsset(java.lang.String, org.librecms.attachments.AttachmentList, java.lang.Class)}
+ * and
+ * {@link #createAsset(java.lang.String, org.librecms.contentsection.Folder, java.lang.Class)}.
+ * Users of this class usually should use these methods. This method has
+ * been made public for special cases. Please note that this class does
+ * not
+ * perform any authorization checks. This is up to the caller.
+ *
+ * @param Type variable for the type of the {@link Asset}.
+ * @param name The name of the new {@link Asset}.
+ * @param folder Optional folder in which the new {@link Asset} is placed.
+ * @param type The type of the new {@link Asset}. Must be a subclass of the
+ * {@link Asset} class.
+ * @return The new {@link Asset}. Note: If no {@link Folder} is provided and
+ * the and the returned {@link Asset} is not added to an
+ * {@link AttachmentList} the new {@code Asset} will become orphaned and
+ * can't be accessed by any method.
+ */
+ @Transactional(Transactional.TxType.REQUIRED)
+ public T createAsset(final String name,
+ final Optional folder,
+ final Class type) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Finds all orphaned {@link Asset}s and deletes them. This method requires
+ * {@code admin} privileges.
+ */
+ @Transactional(Transactional.TxType.REQUIRED)
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ public void deleteOrphanedAssets() {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Moves an {@link Asset} to an folder.
+ *
+ * @param asset The {@link Asset} to move.
+ * @param targetFolder The folder to which the {@link Asset} is moved. Must
+ * be an asset folder.
+ */
+ @AuthorizationRequired
+ @Transactional(Transactional.TxType.REQUIRED)
+ public void move(
+ @RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_EDIT)
+ final Asset asset,
+ @RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_EDIT)
+ final Folder targetFolder) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Copies an {@link Asset}.
+ *
+ * @param asset The {@link Asset} to copy.
+ * @param targetFolder The folder to which the {@link Asset} is copied.
+ */
+ @Transactional(Transactional.TxType.REQUIRED)
+ @AuthorizationRequired
+ public void copy(final Asset asset,
+ @RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_CREATE_NEW)
+ final Folder targetFolder) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Checks if an {@link Asset} is in use. An {@link Asset} is in use if it is
+ * member of at least one {@link AttachmentList}.
+ *
+ * @param asset The {@link Asset} to check for usage.
+ * @return {@code true} if the {@link Asset} is in use, {@link false} if
+ * not.
+ */
+ @Transactional(Transactional.TxType.REQUIRED)
+ public boolean isAssetInUse(final Asset asset) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Returns the path of an shared {@link Asset}. The path of an asset is the
+ * path of the folder category in which the asset is placed concatenated
+ * with the name of the asset. The path is relative to the content section.
+ *
+ * @param asset The {@link Assset} for which the path is generated.
+ * @return The path of the {@link Asset}. If the {@link Asset} is a non
+ * shared asset the path is empty.
+ *
+ * @see #getAssetPath(org.librecms.assets.Asset, boolean)
+ */
+ public String getAssetPath(final Asset asset) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Returns the path of an item as String.
+ *
+ * @param asset The {@link Asset} for which the path is generated.
+ * @param withContentSection Whether to include the content section into the
+ * path or not.
+ * @return The path of the asset.
+ *
+ * @see #getAssetPath(org.librecms.assets.Asset)
+ */
+ public String getAssetPath(final Asset asset,
+ final boolean withContentSection) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Creates a list of the folder in which an asset is placed.
+ *
+ * @param asset
+ * @return
+ */
+ public List getAssetFolders(final Asset asset) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Gets the folder in which an asset is placed.
+ *
+ * @param asset The asset.
+ * @return The folder in which the asset is placed. If the asset is a non
+ * shared asset an empty {@link Optional} is returned.
+ */
+ public Optional getAssetFolder(final Asset asset) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+}
diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemManager.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemManager.java
index 1486be4ba..644cd0049 100644
--- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemManager.java
+++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentItemManager.java
@@ -252,7 +252,7 @@ public class ContentItemManager {
public void move(
@RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_EDIT)
final ContentItem item,
- @RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_EDIT)
+ @RequiresPrivilege(CmsConstants.PRIVILEGE_ITEMS_CREATE_NEW)
final Folder targetFolder) {
if (item == null) {
throw new IllegalArgumentException("The item to move can't be null.");
@@ -318,6 +318,7 @@ public class ContentItemManager {
* @return The copy of the item
*/
@Transactional(Transactional.TxType.REQUIRED)
+ @AuthorizationRequired
@SuppressWarnings("unchecked")
public ContentItem copy(
final ContentItem item,
@@ -999,7 +1000,7 @@ public class ContentItemManager {
* name {@code neural-nets} has the path
* {@code /research/computer-science/artificial-intelligence/neural-nets}.
*
- * @param item The item which path is generated.
+ * @param item The item for which path is generated.
*
* @return The path of the content item
*
@@ -1010,7 +1011,7 @@ public class ContentItemManager {
}
/**
- * Return the path of an as String. The path of an item is the path of the
+ * Returns the path of an item as String. The path of an item is the path of the
* folder category the item is a member of concatenated with the name of the
* item. The path is relative to the content section. For instance, the path
* of an item in the folder category
@@ -1066,7 +1067,7 @@ public class ContentItemManager {
}
/**
- * Creates as list of the folders in which is item is placed.
+ * Creates a list of the folders in which an item is placed.
*
* @param item
*