/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.content.category; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.jdom.CDATA; import org.jdom.Document; import org.jdom.Element; import com.enonic.cms.framework.xml.XMLDocument; import com.enonic.cms.framework.xml.XMLDocumentFactory; import com.enonic.cms.core.CalendarUtil; import com.enonic.cms.core.content.contenttype.ContentHandlerEntity; import com.enonic.cms.core.content.contenttype.ContentTypeEntity; import com.enonic.cms.core.content.contenttype.ContentTypeKey; import com.enonic.cms.core.security.user.UserEntity; public class CategoryXmlCreator { private UserEntity user; private UserEntity anonymousUser; private CategoryAccessResolver categoryAccessResolver; private Set<ContentTypeKey> allowedContentTypes; private boolean includeAutoApproveInfo = true; private boolean includeCreatedAndTimestampInfo = true; private boolean includeAccessRightsInfo = true; private boolean includeOwnerAndModiferInfo = true; private boolean includeDisabledInfo = true; private boolean includeDescriptionInfo = true; private boolean includeSuperCategoryKeyInfo = true; private boolean rootAccess = true; public void setUser( UserEntity user ) { this.user = user; } public void setAnonymousUser( UserEntity user ) { this.anonymousUser = user; } public void setCategoryAccessResolver( CategoryAccessResolver resolver ) { this.categoryAccessResolver = resolver; } public void setIncludeAccessRightsInfo( boolean value ) { this.includeAccessRightsInfo = value; } public void setIncludeSuperCategoryKeyInfo( boolean value ) { this.includeSuperCategoryKeyInfo = value; } public void setIncludeDescriptionInfo( boolean value ) { this.includeDescriptionInfo = value; } public void setIncludeAutoApproveInfo( boolean value ) { this.includeAutoApproveInfo = value; } public void setIncludeCreatedAndTimestampInfo( boolean value ) { this.includeCreatedAndTimestampInfo = value; } public void setIncludeOwnerAndModiferInfo( boolean value ) { this.includeOwnerAndModiferInfo = value; } public void setIncludeDisabledInfo( boolean value ) { this.includeDisabledInfo = value; } public void setAllowedContentType( ContentTypeKey contentType ) { allowedContentTypes = new HashSet<ContentTypeKey>(); allowedContentTypes.add( contentType ); } public void setAllowedContentTypes( Set<ContentTypeKey> contentTypes ) { allowedContentTypes = contentTypes; } public void setRootAccess( boolean rootAccess ) { this.rootAccess = rootAccess; } public XMLDocument createEmptyCategoriesDocument( String message ) { Element root = new Element( "categories" ); Document doc = new Document( root ); if ( ( message != null ) && ( message.length() > 0 ) ) { root.setAttribute( "message", message ); } return XMLDocumentFactory.create( doc ); } public XMLDocument createCategoryBranch( List<CategoryEntity> categories, CategoryKey selectedTopCategory ) { final Element root = new Element( "categories" ); root.setAttribute( "disabled", !rootAccess ? "true" : "false" ); for ( CategoryEntity category : categories ) { if ( isCategoryOrAnyDescendantsOfAllowedContentTypes( category ) ) { boolean includeChildren = category.getKey().equals( selectedTopCategory ) | categories.size() == 1; root.addContent( doCreateCategoryElement( category, includeChildren, null ) ); } } return XMLDocumentFactory.create( new Document( root ) ); } public XMLDocument createCategoryBranch( CategoryEntity category ) { final Element root = new Element( "categories" ); root.addContent( doCreateCategoryElement( category, true, null ) ); return XMLDocumentFactory.create( new Document( root ) ); } public XMLDocument createEmptyCategoryNamesDocument( String message ) { Element root = new Element( "categorynames" ); Document doc = new Document( root ); if ( ( message != null ) && ( message.length() > 0 ) ) { root.setAttribute( "message", message ); } return XMLDocumentFactory.create( doc ); } public XMLDocument createCategoryNames( CategoryEntity category ) { return createCategoryNames( category, null ); } public XMLDocument createCategoryNames( CategoryEntity category, Map<CategoryEntity, Integer> contentCountMap ) { List<CategoryEntity> categories = new ArrayList<CategoryEntity>(); categories.add( category ); return createCategoryNames( categories, contentCountMap ); } public XMLDocument createCategoryNames( List<CategoryEntity> categories, Map<CategoryEntity, Integer> contentCountMap ) { final Element root = new Element( "categorynames" ); boolean includeContentCount = false; if ( contentCountMap != null ) { includeContentCount = true; } for ( CategoryEntity category : categories ) { root.addContent( createCategoryNameElement( category, includeContentCount ? contentCountMap.get( category ) : null ) ); } return XMLDocumentFactory.create( new Document( root ) ); } private Element createCategoryNameElement( CategoryEntity category, Integer contentCount ) { Element element = new Element( "categoryname" ); if ( category != null ) { element.setText( category.getName() ); element.setAttribute( "categorykey", category.getKey().toString() ); if ( category.getContentType() != null ) { element.setAttribute( "contenttypekey", Integer.toString( category.getContentType().getKey() ) ); } if ( category.getParent() != null ) { element.setAttribute( "supercategorykey", category.getParent().getKey().toString() ); } if ( category.getUnitExcludeDeleted() != null ) { element.setAttribute( "unitkey", Integer.toString( category.getUnitExcludeDeleted().getKey().toInt() ) ); } element.setAttribute( "subcategories", category.hasChildren() ? "true" : "false" ); } if ( contentCount != null ) { element.setAttribute( "contentcount", contentCount.toString() ); } return element; } public XMLDocument createCategory( CategoryEntity category ) { if ( category == null ) { throw new IllegalArgumentException( "Given category cannot be null" ); } final Element root = new Element( "categories" ); if ( categoryAccessResolver.hasAccess( user, category, CategoryAccessType.READ ) ) { root.addContent( doCreateCategoryElement( category, false, null ) ); } return XMLDocumentFactory.create( new Document( root ) ); } public Element createCategoryElement( CategoryEntity category, String elementName ) { if ( category == null ) { throw new IllegalArgumentException( "Given category cannot be null" ); } return doCreateCategoryElement( category, false, elementName ); } private Element doCreateCategoryElement( CategoryEntity category, boolean includeChildren, String name ) { final Element categoryEl = new Element( StringUtils.isBlank( name ) ? "category" : name ); categoryEl.setAttribute( "key", category.getKey().toString() ); categoryEl.setAttribute( "name", category.getName() ); categoryEl.setAttribute( "language", category.getUnitExcludeDeleted().getLanguage().getCode() ); categoryEl.setAttribute( "unitkey", String.valueOf( category.getUnitExcludeDeleted().getKey() ) ); if ( includeCreatedAndTimestampInfo ) { categoryEl.setAttribute( "created", CalendarUtil.formatTimestamp( category.getCreated(), false ) ); categoryEl.setAttribute( "timestamp", CalendarUtil.formatTimestamp( category.getTimestamp(), false ) ); } if ( includeAutoApproveInfo ) { categoryEl.setAttribute( "autoApprove", String.valueOf( category.getAutoMakeAvailableAsBoolean() ) ); } applyContentTypeInfo( category, categoryEl ); if ( includeSuperCategoryKeyInfo ) { applySuperCategoryKey( category, categoryEl ); } if ( includeDescriptionInfo ) { applyDescription( category, categoryEl ); } if ( includeDisabledInfo ) { applyDisabledInfo( category, categoryEl ); } if ( includeOwnerAndModiferInfo ) { categoryEl.addContent( createUserElement( "owner", category.getOwner() ) ); categoryEl.addContent( createUserElement( "modifier", category.getModifier() ) ); } if ( includeAccessRightsInfo ) { applyAccessRights( category, categoryEl ); } if ( includeChildren ) { int addedChildren = 0; for ( CategoryEntity childCategory : category.getChildren() ) { boolean hasAdminBrowseAccessOnAnyChild = categoryAccessResolver.hasAdminBrowseAccessWithDescendantsCheck( user, childCategory ); boolean childCategoryIsOfAllowedContentTypes = isCategoryOrAnyDescendantsOfAllowedContentTypes( childCategory ); if ( hasAdminBrowseAccessOnAnyChild && childCategoryIsOfAllowedContentTypes ) { Element childCategoryEl = doCreateCategoryElement( childCategory, includeChildren, null ); categoryEl.addContent( childCategoryEl ); addedChildren++; } } categoryEl.setAttribute( "haschildren", addedChildren > 0 ? "true" : "false" ); } else { categoryEl.setAttribute( "haschildren", category.hasChildren() ? "true" : "false" ); } return categoryEl; } private void applyDisabledInfo( CategoryEntity category, Element categoryEl ) { if ( allowedContentTypes == null ) { categoryEl.setAttribute( "disabled", "false" ); } else { boolean categoryIsOfAllowedContentTypes = isCategoryOfAllowedContentTypes( category ); categoryEl.setAttribute( "disabled", !categoryIsOfAllowedContentTypes ? "true" : "false" ); } } private void applyContentTypeInfo( CategoryEntity category, Element categoryEl ) { ContentTypeEntity contentType = category.getContentType(); if ( contentType != null ) { categoryEl.setAttribute( "contenttypekey", contentType.getContentTypeKey().toString() ); ContentHandlerEntity contentHandler = contentType.getContentHandler(); if ( contentHandler != null ) { categoryEl.setAttribute( "handler", contentHandler.getClassName() ); } } } private void applyDescription( CategoryEntity category, Element categoryEl ) { String description = category.getDescription(); if ( description != null ) { categoryEl.addContent( createCDataSection( "description", description ) ); } } private void applySuperCategoryKey( CategoryEntity category, Element categoryEl ) { CategoryEntity parent = category.getParent(); if ( parent != null ) { categoryEl.setAttribute( "supercategorykey", parent.getKey().toString() ); } } private Element createCDataSection( String name, String data ) { final Element element = new Element( name ); element.addContent( new CDATA( data ) ); return element; } private Element createUserElement( String name, UserEntity user ) { final Element element = new Element( name ); element.setText( user.getDisplayName() ); element.setAttribute( "key", user.getKey().toString() ); element.setAttribute( "uid", user.getName() ); element.setAttribute( "qualifiedName", user.getQualifiedName().toString() ); return element; } private void applyAccessRights( CategoryEntity category, Element categoryEl ) { boolean anonymousReadAccess = categoryAccessResolver.hasAccess( anonymousUser, category, CategoryAccessType.READ ); boolean administrateAccess = categoryAccessResolver.hasAccess( user, category, CategoryAccessType.ADMINISTRATE ); boolean createAccess = categoryAccessResolver.hasAccess( user, category, CategoryAccessType.CREATE ); boolean adminBrowseAccess = categoryAccessResolver.hasAccess( user, category, CategoryAccessType.ADMIN_BROWSE ); categoryEl.setAttribute( "anonaccess", anonymousReadAccess ? "true" : "false" ); categoryEl.setAttribute( "useraccess", adminBrowseAccess ? "true" : "false" ); categoryEl.setAttribute( "useradministrate", administrateAccess ? "true" : "false" ); categoryEl.setAttribute( "usercreate", createAccess ? "true" : "false" ); } private boolean isCategoryOfAllowedContentTypes( CategoryEntity category ) { if ( allowedContentTypes == null ) { return true; } ContentTypeEntity contentType = category.getContentType(); if ( contentType == null ) { return allowedContentTypes.isEmpty(); } return allowedContentTypes.contains( contentType.getContentTypeKey() ); } private boolean isCategoryOrAnyDescendantsOfAllowedContentTypes( CategoryEntity category ) { if ( allowedContentTypes == null ) { return true; } if ( isCategoryOfAllowedContentTypes( category ) ) { return true; } for ( CategoryEntity child : category.getChildren() ) { if ( isCategoryOrAnyDescendantsOfAllowedContentTypes( child ) ) { return true; } } return false; } }