From 40efbfdc6ea3bb9712cf6da399c68c98b5bf42e2 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Mon, 25 Jan 2021 21:50:51 +0100 Subject: [PATCH] Faster (native SQL) queries for folder browsing --- .../src/main/resources/log4j2.xml | 2 + .../WEB-INF/classes/META-INF/persistence.xml | 2 +- .../contentsection/DocumentFolderEntry.java | 172 ++++++ .../org/librecms/contentsection/Folder.java | 201 ++++-- .../contentsection/FolderRepository.java | 31 +- .../librecms/ui/ContentSectionController.java | 572 +++++++++++++----- .../org/librecms/ui/ContentSectionModel.java | 6 +- ...serModel.java => DocumentFolderModel.java} | 10 +- ...Model.java => DocumentFolderRowModel.java} | 6 +- .../ui/content-section/access-denied.xhtml | 19 + .../contentsection-not-found.xhtml | 25 + .../ui/content-section/document-folder.xhtml | 256 ++++++++ .../ui/content-section/folderbrowser.xhtml | 187 ------ .../ui/content-section/testdata.xhtml | 26 + .../org/librecms/CmsAdminMessages.properties | 32 +- .../librecms/CmsAdminMessages_de.properties | 32 +- ccm-wildfly/pom.xml | 2 +- 17 files changed, 1130 insertions(+), 451 deletions(-) create mode 100644 ccm-cms/src/main/java/org/librecms/contentsection/DocumentFolderEntry.java rename ccm-cms/src/main/java/org/librecms/ui/{FolderBrowserModel.java => DocumentFolderModel.java} (81%) rename ccm-cms/src/main/java/org/librecms/ui/{FolderBrowserRowModel.java => DocumentFolderRowModel.java} (94%) create mode 100644 ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/access-denied.xhtml create mode 100644 ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/contentsection-not-found.xhtml create mode 100644 ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/document-folder.xhtml delete mode 100644 ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/folderbrowser.xhtml create mode 100644 ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/testdata.xhtml diff --git a/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml b/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml index e5dac78bf..c2eed1bd8 100644 --- a/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml +++ b/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml @@ -107,5 +107,7 @@ + + diff --git a/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/classes/META-INF/persistence.xml b/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/classes/META-INF/persistence.xml index 682849862..9689a70e3 100644 --- a/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/classes/META-INF/persistence.xml +++ b/ccm-bundle-devel-wildfly/src/main/webapp/WEB-INF/classes/META-INF/persistence.xml @@ -34,7 +34,7 @@ - diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/DocumentFolderEntry.java b/ccm-cms/src/main/java/org/librecms/contentsection/DocumentFolderEntry.java new file mode 100644 index 000000000..b74b073bb --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/contentsection/DocumentFolderEntry.java @@ -0,0 +1,172 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.librecms.contentsection; + +import java.util.Date; +import java.util.Objects; + +/** + * + * @author Jens Pelzetter + */ +public class DocumentFolderEntry { + + private long entryId; + + private String entryUuid; + + private String displayName; + + private String itemClass; + + private Date creationDate; + + private Date lastModified; + + private String version; + + private boolean folder; + + public DocumentFolderEntry() { + + } + + public DocumentFolderEntry( + final long entryId, + final String entryUuid, + final String displayName, + final String itemClass, + final Date creationDate, + final Date lastModified, + final String version, + final boolean folder + ) { + this.entryId = entryId; + this.entryUuid = entryUuid;; + this.displayName = displayName; + this.itemClass = itemClass; + this.creationDate = creationDate; + this.lastModified = lastModified; + this.version = version; + this.folder = folder; + } + + public long getEntryId() { + return entryId; + } + + public void setEntryId(final long entryId) { + this.entryId = entryId; + } + + public String getEntryUuid() { + return entryUuid; + } + + public void setEntryUuid(final String entryUuid) { + this.entryUuid = entryUuid; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(final String displayName) { + this.displayName = displayName; + } + + public String getItemClass() { + return itemClass; + } + + public void setItemClass(final String itemClass) { + this.itemClass = itemClass; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(final Date creationDate) { + this.creationDate = creationDate; + } + + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(final Date lastModified) { + this.lastModified = lastModified; + } + + public String getVersion() { + return version; + } + + public void setVersion(final String version) { + this.version = version; + } + + public boolean isFolder() { + return folder; + } + + public void setFolder(final boolean folder) { + this.folder = folder; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 29 * hash + (int) (entryId ^ (entryId >>> 32)); + hash = 29 * hash + Objects.hashCode(entryUuid); + hash = 29 * hash + Objects.hashCode(displayName); + hash = 29 * hash + Objects.hashCode(itemClass); + hash = 29 * hash + Objects.hashCode(creationDate); + hash = 29 * hash + Objects.hashCode(lastModified); + hash = 29 * hash + Objects.hashCode(version); + hash = 29 * hash + (folder ? 1 : 0); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof DocumentFolderEntry)) { + return false; + } + final DocumentFolderEntry other = (DocumentFolderEntry) obj; + if (!other.canEqual(this)) { + return false; + } + if (entryId != other.getEntryId()) { + return false; + } + if (folder != other.isFolder()) { + return false; + } + if (!Objects.equals(entryUuid, other.getEntryUuid())) { + return false; + } + if (!Objects.equals(displayName, other.getDisplayName())) { + return false; + } + if (version != other.getVersion()) { + return false; + } + return true; + } + + public boolean canEqual(final Object obj) { + return obj instanceof DocumentFolderEntry; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java b/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java index 5114adffd..c77ec1d25 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java @@ -26,18 +26,25 @@ import javax.persistence.Table; import org.libreccm.categorization.Category; import java.io.Serializable; +import java.time.LocalDate; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import javax.persistence.Column; +import javax.persistence.ColumnResult; +import javax.persistence.ConstructorResult; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.JoinTable; +import javax.persistence.NamedNativeQueries; +import javax.persistence.NamedNativeQuery; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; +import javax.persistence.SqlResultSetMapping; +import javax.persistence.SqlResultSetMappings; import static org.librecms.CmsConstants.*; @@ -52,27 +59,23 @@ import static org.librecms.CmsConstants.*; name = "Folder.rootFolders", query = "SELECT f FROM Folder f " + "WHERE f.parentCategory IS NULL " - + " AND f.type = :type") - , + + " AND f.type = :type"), @NamedQuery( name = "Folder.findByName", - query = "SELECT f FROM Folder f WHERE f.name = :name") - , + query = "SELECT f FROM Folder f WHERE f.name = :name"), @NamedQuery( name = "Folder.findSubFolders", query = "SELECT f " + "FROM Folder f" + " WHERE f.parentCategory = :parent " + "ORDER BY f.name" - ) - , + ), @NamedQuery( name = "Folder.countSubFolders", query = "SELECT COUNT(f) " + "FROM Folder f " + "WHERE f.parentCategory = :parent" - ) - , + ), // @NamedQuery( // name = "Folder.findItems", // query = "SELECT c.categorizedObject " @@ -104,66 +107,136 @@ import static org.librecms.CmsConstants.*; + "FROM ContentItem i JOIN i.categories c " + "WHERE c.category = :folder " + "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE" - ) - , + ), @NamedQuery( name = "Folder.findObjects", - query = "SELECT o FROM CcmObject o " - + "WHERE o IN (SELECT f FROM Folder f " - + "WHERE f.parentCategory = :folder " - + "AND LOWER(f.name) LIKE :term) " - + "OR o IN (SELECT i FROM ContentItem i JOIN i.categories c " - + "WHERE c.category = :folder " - + "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' " - + "AND i.version = " - + "org.librecms.contentsection.ContentItemVersion.DRAFT " - + "AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term)) " - // + "OR LOWER(i.name.values) LIKE LOWER(:term)" - + ")) " - + "ORDER BY o.displayName" - // query = "SELECT o FROM CcmObject o " - // + "WHERE o IN (SELECT f FROM Folder f " - // + "WHERE f.parentCategory = :parent " - // + "AND lower(f.name) LIKE :term) " - // + "OR o IN (SELECT c.categorizedObject " - // + "FROM Categorization c " - // + "WHERE c.category = :folder " - // + "AND TYPE(c.categorizedObject) IN ContentItem " - // + "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' " - // + "AND c.version = " - // + "org.librecms.contentsection.ContentItemVersion.DRAFT" - // + "AND (LOWER(c.categorizedObject.displayName) LIKE :term " - // + "OR LOWER(c.categorizedObject.name.value) LIKE :term)) " - // + "ORDER BY o.displayName" - ) - , + query + = "SELECT o FROM CcmObject o WHERE TYPE(O) IN (ContentItem, Folder) AND o IN (SELECT f FROM Category f WHERE TYPE(f) IN (Folder) AND f.parentCategory = :folder AND LOWER(f.name) LIKE LOWER(CONCAT('%', :term))) OR o IN (SELECT i FROM ContentItem i JOIN i.categories c WHERE TYPE(i) IN (ContentItem) AND c.category = :folder AND c.type = '" + + CATEGORIZATION_TYPE_FOLDER + + "' AND i.version = org.librecms.contentsection.ContentItemVersion.DRAFT AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term)))) ORDER BY o.displayName" + ), @NamedQuery( name = "Folder.countObjects", - query = "SELECT COUNT(o) FROM CcmObject o " - + "WHERE o IN (SELECT f FROM Folder f " - + "WHERE f.parentCategory = :folder " - + "AND LOWER(f.name) LIKE :term) " - + "OR o IN (SELECT i FROM ContentItem i JOIN i.categories c " - + "WHERE c.category = :folder " - + "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' " - + "AND i.version = " - + "org.librecms.contentsection.ContentItemVersion.DRAFT " - + "AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term)) " - // + "OR LOWER(i.name.values) LIKE LOWER(:term)" - + "))" - // query = "SELECT COUNT(o) FROM CcmObject o " - // + "WHERE o IN (SELECT f FROM Folder f " - // + "WHERE f.parentCategory = :parent " - // + "AND lower(f.name) LIKE :term) " - // + "OR o IN (SELECT c.categorizedObject AS co " - // + "FROM Categorization c " - // + "WHERE c.category = :folder " - // // + "AND TYPE(co) IN ContentItem " - // + "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' " - // + "AND co.version = " - // + "org.librecms.contentsection.ContentItemVersion.DRAFT " - // + "AND ((LOWER(co.displayName) LIKE :term " - // + "OR LOWER(co.name.value) LIKE :term)))" + query + = "SELECT COUNT(o) FROM CcmObject o WHERE TYPE(O) IN (ContentItem, Folder) AND o IN (SELECT f FROM Category f WHERE TYPE(f) IN (Folder) AND f.parentCategory = :folder AND LOWER(f.name) LIKE LOWER(CONCAT('%', :term))) OR o IN (SELECT i FROM ContentItem i JOIN i.categories c WHERE TYPE(i) IN (ContentItem) AND c.category = :folder AND c.type = '" + + CATEGORIZATION_TYPE_FOLDER + + "' AND i.version = org.librecms.contentsection.ContentItemVersion.DRAFT AND (LOWER(i.displayName) LIKE LOWER(CONCAT('%', :term))))" + ) +}) +@NamedNativeQueries({ + @NamedNativeQuery( + name = "Folder.countDocumentFolderEntries", + query = "SELECT (" + + "(" + + "SELECT COUNT(*) " + + "FROM ccm_core.ccm_objects " + + "JOIN ccm_cms.content_items " + + "ON ccm_objects.object_id = content_items.object_id " + + "JOIN ccm_core.categorizations " + + " ON ccm_objects.object_id " + + " = categorizations.object_id " + + "WHERE categorizations.category_id = :folderId " + + "AND content_items.version = 'DRAFT'" + + ") " + + "+ " + + "(" + + "SELECT COUNT(*) " + + "FROM ccm_core.categories " + + "JOIN ccm_core.ccm_objects " + + " ON categories.object_id = ccm_objects.object_id " + + "JOIN ccm_cms.folders " + + " ON categories.object_id = folders.object_id " + + "WHERE categories.parent_category_id = :folderId " + + "AND folders.type = 'DOCUMENTS_FOLDER'" + + ") AS entries_count", + resultSetMapping = "Folder.countDocumentFolderEntries" + ), + @NamedNativeQuery( + name = "Folder.getDocumentFolderEntries", + query + = "SELECT ccm_objects.object_id AS entry_id, " + + " ccm_objects.uuid AS entry_uuid, " + + " ccm_objects.display_name AS display_name, " + + " content_types.content_item_class AS item_class, " + + " content_items.creation_date AS creation_date, " + + " content_items.last_modified AS last_modified, " + + " content_items.\"version\" AS version, " + + " false AS is_folder " + + "FROM ccm_cms.content_items " + + "JOIN ccm_core.ccm_objects " + + " ON ccm_cms.content_items.object_id " + + " = ccm_core.ccm_objects.object_id " + + "JOIN ccm_core.categorizations " + + " ON ccm_objects.object_id " + + " = ccm_core.categorizations.object_id " + + "JOIN ccm_cms.content_types " + + " ON content_items.content_type_id " + + " = content_types.object_id " + + "WHERE categorizations.category_id = :folderId " + + "AND content_items.\"version\" ='DRAFT' " + + "UNION " + + "SELECT categories.object_id AS entry_id, " + + " ccm_objects.uuid AS entry_uuid, " + + " categories.\"name\" AS display_name, " + + " null AS item_class, " + + " null AS creation_date, " + + " null AS last_modified, " + + " null AS version, " + + " true as is_folder " + + "FROM ccm_core.categories " + + "JOIN ccm_core.ccm_objects " + + " ON categories.object_id = ccm_objects.object_id " + + "JOIN ccm_cms.folders " + + " ON categories.object_id = folders.object_id " + + "WHERE categories.parent_category_id = :folderId " + + "AND folders.\"type\" = 'DOCUMENTS_FOLDER'", + resultSetMapping = "Folder.DocumentFolderEntry" + ) +}) +@SqlResultSetMappings({ + @SqlResultSetMapping( + name = "Folder.countDocumentFolderEntries", + columns = { + @ColumnResult(name = "entries_count", type = long.class) + } + ), + @SqlResultSetMapping( + name = "Folder.DocumentFolderEntry", + classes = { + @ConstructorResult( + columns = { + @ColumnResult(name = "entry_id", type = long.class), + @ColumnResult(name = "entry_uuid"), + @ColumnResult(name = "display_name"), + @ColumnResult(name = "item_class"), + @ColumnResult(name = "creation_date"), + @ColumnResult(name = "last_modified"), + @ColumnResult(name = "version"), + @ColumnResult(name = "is_folder", type = boolean.class) + }, + targetClass = DocumentFolderEntry.class + ),} + // entities = { + // @EntityResult( + // entityClass = DocumentFolderEntry.class, + // fields = { + // @FieldResult(column = "entry_id", name = "entryId"), + // @FieldResult(column = "entry_uuid", name = "entryUuid"), + // @FieldResult(column = "display_name", name = "displayName"), + // @FieldResult(column = "item_class", name = "itemClass"), + // @FieldResult( + // column = "creation_date", + // name = "creation_date" + // ), + // @FieldResult( + // column = "last_modified", + // name = "lastModified" + // ), + // @FieldResult(column = "version", name = "version"), + // @FieldResult(column = "is_folder", name = "folder") + // } + // ) + // } ) }) public class Folder extends Category implements Serializable { diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/FolderRepository.java b/ccm-cms/src/main/java/org/librecms/contentsection/FolderRepository.java index e8207abff..ab3e8e5a2 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/FolderRepository.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/FolderRepository.java @@ -277,10 +277,39 @@ public class FolderRepository extends AbstractEntityRepository { .getResultList(); } + public List getDocumentFolderEntries( + final Folder folder, + final int firstResult, + final int maxResults, + final String term + ) { + return getEntityManager() + .createNamedQuery( + "Folder.getDocumentFolderEntries", DocumentFolderEntry.class + ) + .setParameter( + "folderId", Objects.requireNonNull(folder).getObjectId() + ) + .setFirstResult(firstResult) + .setMaxResults(maxResults) + .getResultList(); + } + + public long countDocumentFolderEntries( + final Folder folder, + final String term + ) { + return getEntityManager() + .createNamedQuery("Folder.countDocumentFolderEntries", Long.class) + .setParameter( + "folderId", Objects.requireNonNull(folder).getObjectId() + ).getSingleResult(); + } + public long countObjectsInFolder(final Folder folder) { return countObjectsInFolder(folder, ""); } - + public long countObjectsInFolder(final Folder folder, final String term) { return getEntityManager() .createNamedQuery("Folder.countObjects", Long.class) diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionController.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionController.java index 05bed4246..88cb29bb7 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionController.java +++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionController.java @@ -5,22 +5,29 @@ */ package org.librecms.ui; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.libreccm.api.Identifier; import org.libreccm.api.IdentifierParser; import org.libreccm.core.CcmObject; import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.security.AuthorizationRequired; +import org.libreccm.security.PermissionChecker; import org.librecms.contentsection.ContentItem; import org.librecms.contentsection.ContentItemL10NManager; import org.librecms.contentsection.ContentItemManager; +import org.librecms.contentsection.ContentItemRepository; import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.ContentSectionRepository; import org.librecms.contentsection.ContentType; import org.librecms.contentsection.ContentTypeManager; import org.librecms.contentsection.ContentTypeRepository; +import org.librecms.contentsection.DocumentFolderEntry; import org.librecms.contentsection.Folder; import org.librecms.contentsection.FolderManager; import org.librecms.contentsection.FolderRepository; +import org.librecms.contentsection.privileges.ItemPrivileges; +import org.librecms.contenttypes.Article; import java.time.LocalDate; import java.time.ZoneId; @@ -30,6 +37,7 @@ import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Optional; import java.util.TreeSet; import java.util.stream.Collectors; @@ -43,7 +51,6 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; /** * @@ -54,12 +61,19 @@ import javax.ws.rs.WebApplicationException; @Path("/{sectionIdentifier}") public class ContentSectionController { + private static final Logger LOGGER = LogManager.getLogger( + ContentSectionController.class + ); + @Inject private CmsAdminMessages cmsAdminMessages; @Inject private ContentItemManager itemManager; + @Inject + private ContentItemRepository itemRepo; + @Inject private ContentItemL10NManager itemL10NManager; @@ -73,7 +87,7 @@ public class ContentSectionController { private ContentTypeRepository contentTypeRepo; @Inject - private FolderBrowserModel folderBrowserModel; + private DocumentFolderModel documentFolderModel; @Inject private FolderManager folderManager; @@ -93,8 +107,11 @@ public class ContentSectionController { @Inject private IdentifierParser identifierParser; + @Inject + private PermissionChecker permissionChecker; + @GET - @Path("/folderbrowser") + @Path("/document-folders") @AuthorizationRequired @Transactional(Transactional.TxType.REQUIRED) public String listItems( @@ -102,202 +119,427 @@ public class ContentSectionController { @QueryParam("firstResult") @DefaultValue("0") final int firstResult, @QueryParam("maxResults") @DefaultValue("20") final int maxResults ) { + final long start = System.currentTimeMillis(); final Identifier identifier = identifierParser.parseIdentifier( sectionIdentifier ); - final ContentSection section; + final Optional sectionResult; switch (identifier.getType()) { case ID: - section = sectionRepo - .findById(Long.parseLong(identifier.getIdentifier())) - .orElseThrow( - () -> new WebApplicationException( - String.format( - "No ContentSection with ID %s found.", - identifier.getIdentifier() - ) - ) - ); + sectionResult = sectionRepo.findById( + Long.parseLong(identifier.getIdentifier()) + ); break; case UUID: - section = sectionRepo - .findByUuid(identifier.getIdentifier()) - .orElseThrow( - () -> new WebApplicationException( - String.format( - "No ContentSection with UUID %s found.", - identifier.getIdentifier() - ) - ) - ); + sectionResult = sectionRepo.findByUuid(identifier + .getIdentifier()); break; default: - section = sectionRepo - .findByLabel(identifier.getIdentifier()) - .orElseThrow( - () -> new WebApplicationException( - String.format( - "No ContentSection named %s found.", - identifier.getIdentifier() - ) - ) - ); + sectionResult = sectionRepo.findByLabel(identifier + .getIdentifier()); break; } + LOGGER.info("Retrieved content section in {} ms", System + .currentTimeMillis() - start); - contentSectionModel.setSection(section); + if (sectionResult.isPresent()) { + final ContentSection section = sectionResult.get(); - final List objects = folderRepo - .findObjectsInFolder( - section.getRootDocumentsFolder(), firstResult, maxResults - ); - folderBrowserModel.setCount( - folderRepo.countObjectsInFolder(section.getRootDocumentsFolder()) - ); - folderBrowserModel.setFirstResult(firstResult); - folderBrowserModel.setMaxResults(maxResults); + final long permissionCheckStart = System.currentTimeMillis(); + if (permissionChecker.isPermitted( + ItemPrivileges.EDIT, section.getRootDocumentsFolder() + )) { + contentSectionModel.setSection(section); + LOGGER.info("Checked in permisisons in {} ms.", System + .currentTimeMillis() - permissionCheckStart); - folderBrowserModel.setRows( - objects - .stream() - .map(object -> buildRowModel(section, object)) - .collect(Collectors.toList()) - ); + final long objectsStart = System.currentTimeMillis(); +// final List objects = folderRepo +// .findObjectsInFolder( +// section.getRootDocumentsFolder(), firstResult, +// maxResults +// ); + final List folderEntries = folderRepo + .getDocumentFolderEntries( + section.getRootDocumentsFolder(), + firstResult, + maxResults, + "" + ); + LOGGER.info("Retrieved objects in {} ms", System + .currentTimeMillis() - objectsStart); + documentFolderModel.setCount( + // folderRepo + // .countObjectsInFolder(section.getRootDocumentsFolder()) + folderRepo.countDocumentFolderEntries( + section.getRootDocumentsFolder(), "" + ) + ); + documentFolderModel.setFirstResult(firstResult); + documentFolderModel.setMaxResults(maxResults); + LOGGER.info( + "Retrieved and counted objects in {} ms", + System.currentTimeMillis() - objectsStart + ); - return "org/librecms/ui/content-section/folderbrowser.xhtml"; + final long rowsStart = System.currentTimeMillis(); +// documentFolderModel.setRows( +// objects +// .stream() +// .map(object -> buildRowModel(section, object)) +// .collect(Collectors.toList()) +// ); + documentFolderModel.setRows( + folderEntries + .stream() + .map(entry -> buildRowModel(section, entry)) + .collect(Collectors.toList()) + ); + LOGGER.info("Build rows in {} ms.", System.currentTimeMillis() + - rowsStart); + + return "org/librecms/ui/content-section/document-folder.xhtml"; + } else { + models.put("sectionidentifier", sectionIdentifier); + return "org/librecms/ui/content-section/access-denied.xhtml"; + } + } else { + models.put("sectionIdentifier", sectionIdentifier); + return "org/librecms/ui/content-section/contentsection-not-found.xhtml"; + } } - private FolderBrowserRowModel buildRowModel( - final ContentSection section, final CcmObject object + @GET + @Path("/create-testdata") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String createTestData( + @PathParam("sectionIdentifier") final String sectionIdentifier + ) { + final Identifier identifier = identifierParser.parseIdentifier( + sectionIdentifier + ); + final Optional sectionResult; + switch (identifier.getType()) { + case ID: + sectionResult = sectionRepo.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + sectionResult = sectionRepo.findByUuid(identifier + .getIdentifier()); + break; + default: + sectionResult = sectionRepo.findByLabel(identifier + .getIdentifier()); + break; + } + + if (sectionResult.isPresent()) { + final ContentSection section = sectionResult.get(); + + if (permissionChecker.isPermitted( + ItemPrivileges.EDIT, section.getRootDocumentsFolder() + )) { + if (section.getRootDocumentsFolder().getObjects().isEmpty()) { + folderManager.createFolder( + "folder-1", section.getRootDocumentsFolder() + ); + final Folder folder2 = folderManager.createFolder( + "folder-2", section.getRootDocumentsFolder() + ); + folderManager.createFolder( + "folder-3", section.getRootDocumentsFolder() + ); + + final Article article = itemManager.createContentItem( + "test-article", + section, + section.getRootDocumentsFolder(), + Article.class, + Locale.ENGLISH + ); + article.getTitle().addValue(Locale.ENGLISH, "Article 1"); + article.getTitle().addValue(Locale.GERMAN, "Artikel 1"); + itemRepo.save(article); + + final Folder folder2a = folderManager.createFolder( + "folder-2a", folder2 + ); + + final Article article2 = itemManager.createContentItem( + "test-article-in-folder-2", + section, + folder2, + Article.class, + Locale.ENGLISH + ); + article2.getTitle().addValue( + Locale.ENGLISH, "Article in Folder 2" + ); + article2.getTitle().addValue( + Locale.GERMAN, "Artikel in Ordner 2" + ); + + models.put( + "testdataMessage", "Test data created successfully." + ); + return "org/librecms/ui/content-section/testdata.xhtml"; + } else { + models.put( + "testdataMessage", "Test data was already created..." + ); + return "org/librecms/ui/content-section/testdata.xhtml"; + } + } else { + models.put("sectionidentifier", sectionIdentifier); + return "org/librecms/ui/content-section/access-denied.xhtml"; + } + } else { + models.put("sectionIdentifier", sectionIdentifier); + return "org/librecms/ui/content-section/contentsection-not-found.xhtml"; + } + } + + private DocumentFolderRowModel buildRowModel( + final ContentSection section, final DocumentFolderEntry entry ) { Objects.requireNonNull(section); - Objects.requireNonNull(object); - if (object instanceof ContentItem) { - return buildRowModel(section, (ContentItem) object); - } else if (object instanceof Folder) { - return buildRowModel(section, (Folder) object); - } else { - final FolderBrowserRowModel row = new FolderBrowserRowModel(); + Objects.requireNonNull(entry); + final DocumentFolderRowModel row = new DocumentFolderRowModel(); + if (entry.isFolder()) { + final Folder folder = folderRepo + .findById(entry.getEntryId()) + .get(); row.setCreated(""); - row.setDeletable(false); - row.setIsFolder(false); + row.setDeletable( + folderManager + .folderIsDeletable(folder) + == FolderManager.FolderIsDeletable.YES + ); + row.setIsFolder(true); row.setLanguages(Collections.emptySortedSet()); row.setLastEditPublished(false); row.setLastEdited(""); - row.setName(object.getDisplayName()); - row.setTitle(""); - row.setType(object.getClass().getSimpleName()); - - return row; - } - } - - private FolderBrowserRowModel buildRowModel( - final ContentSection section, final ContentItem contentItem - ) { - Objects.requireNonNull(section); - Objects.requireNonNull(contentItem); - - final FolderBrowserRowModel row = new FolderBrowserRowModel(); - row.setCreated( - DateTimeFormatter.ISO_DATE.format( - LocalDate.ofInstant( - contentItem.getCreationDate().toInstant(), - ZoneId.systemDefault() + row.setName(entry.getDisplayName()); + row.setTitle( + globalizationHelper.getValueFromLocalizedString( + folder.getTitle() ) - ) - ); - row.setDeletable(!itemManager.isLive(contentItem)); - row.setIsFolder(false); - row.setLanguages( - new TreeSet<>( - itemL10NManager - .availableLanguages(contentItem) - .stream() - .map(Locale::toString) - .collect(Collectors.toSet()) - ) - ); - if (itemManager.isLive(contentItem)) { - final LocalDate draftLastModified = LocalDate.ofInstant( - contentItem.getLastModified().toInstant(), - ZoneId.systemDefault() ); - final LocalDate liveLastModified = LocalDate.ofInstant( - itemManager - .getLiveVersion(contentItem, contentItem.getClass()) - .map(ContentItem::getLastModified) - .map(Date::toInstant) - .get(), - ZoneId.systemDefault() + row.setType( + globalizationHelper.getLocalizedTextsUtil( + "org.librecms.CmsAdminMessages" + ).getText("contentsection.documentfolder.types.folder") ); - row.setLastEditPublished( - liveLastModified.isBefore(draftLastModified) - ); - } else { - row.setLastEditPublished(false); - } - - row.setLastEdited( - DateTimeFormatter.ISO_DATE.format( - LocalDate.ofInstant( + final ContentItem contentItem = itemRepo + .findById(entry.getEntryId()) + .get(); + row.setCreated( + DateTimeFormatter.ISO_DATE.format( + LocalDate.ofInstant( + contentItem.getCreationDate().toInstant(), + ZoneId.systemDefault() + ) + ) + ); + row.setDeletable(!itemManager.isLive(contentItem)); + row.setIsFolder(false); + row.setLanguages( + new TreeSet<>( + itemL10NManager + .availableLanguages(contentItem) + .stream() + .map(Locale::toString) + .collect(Collectors.toSet()) + ) + ); + if (itemManager.isLive(contentItem)) { + final LocalDate draftLastModified = LocalDate.ofInstant( contentItem.getLastModified().toInstant(), ZoneId.systemDefault() - ) - ) - ); - row.setName(contentItem.getDisplayName()); - row.setNoneCmsObject(false); - row.setTitle( - globalizationHelper.getValueFromLocalizedString( - contentItem.getTitle() - ) - ); - row.setType( - contentTypeRepo - .findByContentSectionAndClass(section, contentItem.getClass()) - .map(ContentType::getLabel) - .map( - label -> globalizationHelper.getValueFromLocalizedString( - label + ); + final LocalDate liveLastModified = LocalDate.ofInstant( + itemManager + .getLiveVersion(contentItem, contentItem.getClass()) + .map(ContentItem::getLastModified) + .map(Date::toInstant) + .get(), + ZoneId.systemDefault() + ); + row.setLastEditPublished( + liveLastModified.isBefore(draftLastModified) + ); + } else { + row.setLastEditPublished(false); + } + + row.setLastEdited( + DateTimeFormatter.ISO_DATE.format( + LocalDate.ofInstant( + contentItem.getLastModified().toInstant(), + ZoneId.systemDefault() ) - ).orElse("?") - ); + ) + ); + row.setName(entry.getDisplayName()); + row.setNoneCmsObject(false); + row.setTitle( + globalizationHelper.getValueFromLocalizedString( + contentItem.getTitle() + ) + ); + row.setType( + contentTypeRepo + .findByContentSectionAndClass(section, contentItem + .getClass()) + .map(ContentType::getLabel) + .map( + label -> globalizationHelper + .getValueFromLocalizedString( + label + ) + ).orElse("?") + ); + + } return row; } - private FolderBrowserRowModel buildRowModel( - final ContentSection section, final Folder folder - ) { - Objects.requireNonNull(section); - Objects.requireNonNull(folder); - - final FolderBrowserRowModel row = new FolderBrowserRowModel(); - row.setCreated(""); - row.setDeletable( - folderManager.folderIsDeletable(folder) - == FolderManager.FolderIsDeletable.YES - ); - row.setIsFolder(true); - row.setLanguages(Collections.emptySortedSet()); - row.setLastEditPublished(false); - row.setLastEdited(""); - row.setName(folder.getDisplayName()); - row.setNoneCmsObject(false); - row.setTitle( - globalizationHelper.getValueFromLocalizedString(folder.getTitle()) - ); - row.setType( - globalizationHelper.getLocalizedTextsUtil( - "org.libreccms.CmsAdminMessages" - ).getText("contentsection.folderbrowser.types.folder") - ); - - return row; - } - +// private DocumentFolderRowModel buildRowModel( +// final ContentSection section, final CcmObject object +// ) { +// Objects.requireNonNull(section); +// Objects.requireNonNull(object); +// if (object instanceof ContentItem) { +// return buildRowModel(section, (ContentItem) object); +// } else if (object instanceof Folder) { +// return buildRowModel(section, (Folder) object); +// } else { +// final DocumentFolderRowModel row = new DocumentFolderRowModel(); +// +// row.setCreated(""); +// row.setDeletable(false); +// row.setIsFolder(false); +// row.setLanguages(Collections.emptySortedSet()); +// row.setLastEditPublished(false); +// row.setLastEdited(""); +// row.setName(object.getDisplayName()); +// row.setTitle(""); +// row.setType(object.getClass().getSimpleName()); +// +// return row; +// } +// } +// +// private DocumentFolderRowModel buildRowModel( +// final ContentSection section, final ContentItem contentItem +// ) { +// Objects.requireNonNull(section); +// Objects.requireNonNull(contentItem); +// +// final DocumentFolderRowModel row = new DocumentFolderRowModel(); +// row.setCreated( +// DateTimeFormatter.ISO_DATE.format( +// LocalDate.ofInstant( +// contentItem.getCreationDate().toInstant(), +// ZoneId.systemDefault() +// ) +// ) +// ); +// row.setDeletable(!itemManager.isLive(contentItem)); +// row.setIsFolder(false); +// row.setLanguages( +// new TreeSet<>( +// itemL10NManager +// .availableLanguages(contentItem) +// .stream() +// .map(Locale::toString) +// .collect(Collectors.toSet()) +// ) +// ); +// if (itemManager.isLive(contentItem)) { +// final LocalDate draftLastModified = LocalDate.ofInstant( +// contentItem.getLastModified().toInstant(), +// ZoneId.systemDefault() +// ); +// final LocalDate liveLastModified = LocalDate.ofInstant( +// itemManager +// .getLiveVersion(contentItem, contentItem.getClass()) +// .map(ContentItem::getLastModified) +// .map(Date::toInstant) +// .get(), +// ZoneId.systemDefault() +// ); +// row.setLastEditPublished( +// liveLastModified.isBefore(draftLastModified) +// ); +// +// } else { +// row.setLastEditPublished(false); +// } +// +// row.setLastEdited( +// DateTimeFormatter.ISO_DATE.format( +// LocalDate.ofInstant( +// contentItem.getLastModified().toInstant(), +// ZoneId.systemDefault() +// ) +// ) +// ); +// row.setName(contentItem.getDisplayName()); +// row.setNoneCmsObject(false); +// row.setTitle( +// globalizationHelper.getValueFromLocalizedString( +// contentItem.getTitle() +// ) +// ); +// row.setType( +// contentTypeRepo +// .findByContentSectionAndClass(section, contentItem.getClass()) +// .map(ContentType::getLabel) +// .map( +// label -> globalizationHelper.getValueFromLocalizedString( +// label +// ) +// ).orElse("?") +// ); +// +// return row; +// } +// +// private DocumentFolderRowModel buildRowModel( +// final ContentSection section, final Folder folder +// ) { +// Objects.requireNonNull(section); +// Objects.requireNonNull(folder); +// +// final DocumentFolderRowModel row = new DocumentFolderRowModel(); +// row.setCreated(""); +// row.setDeletable( +// folderManager.folderIsDeletable(folder) +// == FolderManager.FolderIsDeletable.YES +// ); +// row.setIsFolder(true); +// row.setLanguages(Collections.emptySortedSet()); +// row.setLastEditPublished(false); +// row.setLastEdited(""); +// row.setName(folder.getDisplayName()); +// row.setNoneCmsObject(false); +// row.setTitle( +// globalizationHelper.getValueFromLocalizedString(folder.getTitle()) +// ); +// row.setType( +// globalizationHelper.getLocalizedTextsUtil( +// "org.librecms.CmsAdminMessages" +// ).getText("contentsection.documentfolder.types.folder") +// ); +// +// return row; +// } } diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionModel.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionModel.java index 3f32477ae..b901c04ad 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionModel.java +++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionModel.java @@ -8,6 +8,7 @@ package org.librecms.ui; import org.librecms.contentsection.ContentSection; import java.util.Objects; +import java.util.Optional; import javax.enterprise.context.RequestScoped; import javax.inject.Named; @@ -29,7 +30,10 @@ public class ContentSectionModel { } public String getSectionName() { - return section.getLabel(); + return Optional + .ofNullable(section) + .map(ContentSection::getLabel) + .orElse(""); } } diff --git a/ccm-cms/src/main/java/org/librecms/ui/FolderBrowserModel.java b/ccm-cms/src/main/java/org/librecms/ui/DocumentFolderModel.java similarity index 81% rename from ccm-cms/src/main/java/org/librecms/ui/FolderBrowserModel.java rename to ccm-cms/src/main/java/org/librecms/ui/DocumentFolderModel.java index 0a72e2533..58a218327 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/FolderBrowserModel.java +++ b/ccm-cms/src/main/java/org/librecms/ui/DocumentFolderModel.java @@ -11,13 +11,15 @@ import java.util.Collections; import java.util.List; import javax.enterprise.context.RequestScoped; +import javax.inject.Named; /** * * @author Jens Pelzetter */ @RequestScoped -public class FolderBrowserModel { +@Named("DocumentFolderModel") +public class DocumentFolderModel { private long count; @@ -25,7 +27,7 @@ public class FolderBrowserModel { private int maxResults; - private List rows; + private List rows; public long getCount() { return count; @@ -51,11 +53,11 @@ public class FolderBrowserModel { this.maxResults = maxResults; } - public List getRows() { + public List getRows() { return Collections.unmodifiableList(rows); } - protected void setRows(final List rows) { + protected void setRows(final List rows) { this.rows = new ArrayList<>(rows); } diff --git a/ccm-cms/src/main/java/org/librecms/ui/FolderBrowserRowModel.java b/ccm-cms/src/main/java/org/librecms/ui/DocumentFolderRowModel.java similarity index 94% rename from ccm-cms/src/main/java/org/librecms/ui/FolderBrowserRowModel.java rename to ccm-cms/src/main/java/org/librecms/ui/DocumentFolderRowModel.java index 35e62f256..f71b78a7b 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/FolderBrowserRowModel.java +++ b/ccm-cms/src/main/java/org/librecms/ui/DocumentFolderRowModel.java @@ -12,7 +12,7 @@ import java.util.SortedSet; * * @author Jens Pelzetter */ -public class FolderBrowserRowModel { +public class DocumentFolderRowModel { private String created; @@ -61,6 +61,10 @@ public class FolderBrowserRowModel { public SortedSet getLanguages() { return Collections.unmodifiableSortedSet(languages); } + + public String getLanguagesAsString() { + return String.join(", ", languages); + } protected void setLanguages(final SortedSet languages) { this.languages = languages; diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/access-denied.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/access-denied.xhtml new file mode 100644 index 000000000..6037e6be9 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/access-denied.xhtml @@ -0,0 +1,19 @@ + + + + Content Section #{ContentSectionModel.sectionName} #{title} - LibreCMS + + + +
+
+ #{CmsAdminMessages.getMessage("contentsection.accessdenied", [sectionidentifier])} +
+
+ + diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/contentsection-not-found.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/contentsection-not-found.xhtml new file mode 100644 index 000000000..566a36934 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/contentsection-not-found.xhtml @@ -0,0 +1,25 @@ +]> + + + + + + + + + + +
+ +
+
+
+ diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/document-folder.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/document-folder.xhtml new file mode 100644 index 000000000..5000e5eeb --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/document-folder.xhtml @@ -0,0 +1,256 @@ +]> + + + + + + + + + + +
+

#{CmsAdminMessages.getMessage("contentsection.documentfolder.heading", [ContentSectionModel.sectionName])}

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ #{CmsAdminMessages['contentsection.documentfolder.headers.name.label']} + + #{CmsAdminMessages['contentsection.documentfolder.headers.languages.label']} + + #{CmsAdminMessages['contentsection.documentfolder.headers.title.label']} + + #{CmsAdminMessages['contentsection.documentfolder.headers.type.label']} + + #{CmsAdminMessages['contentsection.documentfolder.headers.creationdate.label']} + + #{CmsAdminMessages['contentsection.documentfolder.headers.lastedit.label']} + + #{CmsAdminMessages['contentsection.documentfolder.headers.actions.label']} +
#{row.name} + #{row.languagesAsString} + #{row.title}#{row.type}#{row.created} + #{row.lastEdited} + + + + + + + #{CmsAdminMessages['contentsection.documentfolder.cols.lastedit.published']} + + + + + + #{CmsAdminMessages['contentsection.documentfolder.cols.lastedit.unpublished']} + + + + + + + +
+ +
+
+
+
+ +
+ diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/folderbrowser.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/folderbrowser.xhtml deleted file mode 100644 index a9a531d4c..000000000 --- a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/folderbrowser.xhtml +++ /dev/null @@ -1,187 +0,0 @@ -]> - - - - - - - - - - -
-

#{CmsAdminMessages.getMessage("folderbrowser.heading", [ContentSectionModel.sectionName])}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- #{CmsAdminMessages['contentsection.folderbrowser.headers.name.label']} - - #{CmsAdminMessages['contentsection.folderbrowser.headers.languages.label']} - - #{CmsAdminMessages['contentsection.folderbrowser.headers.title.label']} - - #{CmsAdminMessages['contentsection.folderbrowser.headers.type.label']} - - #{CmsAdminMessages['contentsection.folderbrowser.headers.creationdate.label']} - - #{CmsAdminMessages['contentsection.folderbrowser.headers.lastedit.label']} - - #{CmsAdminMessages['contentsection.folderbrowser.headers.actions.label']} -
folder-1Folder 1Ordner2021-01-20 08:592021-01-20 08:59
an-itemde, enAn itemArticle2021-01-20 09:03 - 2021-01-20 10:11 - - - - #{CmsAdminMessages['contentsection.folderbrowser.cols.lastedit.published']} -
unpublished-itemde, enUnppublished item itemArticle2021-01-20 10:31 - 2021-01-20 10:34 - - - - #{CmsAdminMessages['contentsection.folderbrowser.cols.lastedit.unpublished']} - - -
-
-
-
- -
- diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/testdata.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/testdata.xhtml new file mode 100644 index 000000000..30e31c278 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/content-section/testdata.xhtml @@ -0,0 +1,26 @@ +]> + + + + + + + + + + +
+ +
+
+
+ + diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties index 8f22d3d9b..612a158f8 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties @@ -24,17 +24,23 @@ contentsections.edit_dialog.close=Cancel contentsections.edit_dialog.name.label=Name contentsections.edit_dialog.save=Rename content section contentsections.edit_dialog.name.help=The name of the content section. Can only contain the letters a to z, the numbers 0-9, the hyphen and the underscore. -folderbrowser.title=Folder Browser -folderbrowser.heading=Content Section {0} Folderbrowser -contentsection.folderbrowser.headers.name.label=Name -contentsection.folderbrowser.headers.languages.label=Languages -contentsection.folderbrowser.headers.title.label=Title -contentsection.folderbrowser.headers.type.label=Type -contentsection.folderbrowser.headers.creationdate.label=Created -contentsection.folderbrowser.headers.lastedit.label=Last edit -contentsection.folderbrowser.headers.actions.label=Aktionen -contentsection.folderbrowser.cols.lastedit.published=Published -contentsection.folderbrowser.cols.lastedit.unpublished=Not published yet -contentsection.folderbrowser.actions.delete.button.label=Delete -contentsection.folderbrowser.foldersnav.subfolders.expand=Show subfolders of +contentsection.documentfolder.title=Document Folders +contentsection.documentfolder.heading=Content Section {0} Documents Folder +contentsection.documentfolder.headers.name.label=Name +contentsection.documentfolder.headers.languages.label=Languages +contentsection.documentfolder.headers.title.label=Title +contentsection.documentfolder.headers.type.label=Type +contentsection.documentfolder.headers.creationdate.label=Created +contentsection.documentfolder.headers.lastedit.label=Last edit +contentsection.documentfolder.headers.actions.label=Aktionen +contentsection.documentfolder.cols.lastedit.published=Published +contentsection.documentfolder.cols.lastedit.unpublished=Not published yet +contentsection.documentfolder.actions.delete.button.label=Delete +contentsection.documentfolder.foldersnav.subfolders.expand=Show subfolders of org.libreccms.CmsAdminMessages=Folder +contentsection.documentfolder.pagination.label=Pages +contentsection.documentfolder.pagination.previous_page=Previous page +contentsection.documentfolder.pagination.next_page=Next page +contentsection.not_found=No content section identifed by {0} available. +contentsection.accessdenied=Your are not permitted to access content section {0}. +contentsection.documentfolder.types.folder=Folder diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties index 93777e94e..e80840f16 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties @@ -24,17 +24,23 @@ contentsections.edit_dialog.close=Abbrechen contentsections.edit_dialog.name.label=Name contentsections.edit_dialog.save=Content Section umbenennen contentsections.edit_dialog.name.help=Der Name der Content Section. Darf nur die Zeichen a bis z, 0-9, the Bindestrich und den Unterstrich enthalten. -folderbrowser.title=Ordner -folderbrowser.heading=Content Section {0} Ordner -contentsection.folderbrowser.headers.name.label=Name -contentsection.folderbrowser.headers.languages.label=Sprachen -contentsection.folderbrowser.headers.title.label=Titel -contentsection.folderbrowser.headers.type.label=Typ -contentsection.folderbrowser.headers.creationdate.label=Erstellt -contentsection.folderbrowser.headers.lastedit.label=Letzte \u00c4nderung -contentsection.folderbrowser.headers.actions.label=Aktionen -contentsection.folderbrowser.cols.lastedit.published=Publiziert -contentsection.folderbrowser.cols.lastedit.unpublished=Nicht nicht publiziert -contentsection.folderbrowser.actions.delete.button.label=L\u00f6schen -contentsection.folderbrowser.foldersnav.subfolders.expand=Unterordner anzeigen +contentsection.documentfolder.title=Dokumenten-Ordner +contentsection.documentfolder.heading=Content Section {0} Dokumenten-Ordner +contentsection.documentfolder.headers.name.label=Name +contentsection.documentfolder.headers.languages.label=Sprachen +contentsection.documentfolder.headers.title.label=Titel +contentsection.documentfolder.headers.type.label=Typ +contentsection.documentfolder.headers.creationdate.label=Erstellt +contentsection.documentfolder.headers.lastedit.label=Letzte \u00c4nderung +contentsection.documentfolder.headers.actions.label=Aktionen +contentsection.documentfolder.cols.lastedit.published=Publiziert +contentsection.documentfolder.cols.lastedit.unpublished=Nicht nicht publiziert +contentsection.documentfolder.actions.delete.button.label=L\u00f6schen +contentsection.documentfolder.foldersnav.subfolders.expand=Unterordner anzeigen org.libreccms.CmsAdminMessages=Ordner +contentsection.documentfolder.pagination.label=Seiten +contentsection.documentfolder.pagination.previous_page=Eine Seite zur\u00fcck +contentsection.documentfolder.pagination.next_page=Eine Seite weiter +contentsection.not_found=Keine Content Section mit dem Identifier {0} gefunden. +contentsection.accessdenied=Sind sind nicht berechtigt auf die Content Section {0} zuzugreifen. +contentsection.documentfolder.types.folder=Ordner diff --git a/ccm-wildfly/pom.xml b/ccm-wildfly/pom.xml index b52f5806a..88b6a8546 100644 --- a/ccm-wildfly/pom.xml +++ b/ccm-wildfly/pom.xml @@ -19,7 +19,7 @@ org.libreccm ccm-wildfly 7.0.0-SNAPSHOT - CCM Wildfly Integration + LibreCCM Wildfly Integration Wildfly specific stuff for CCM.