/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.content; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import org.apache.commons.lang.StringUtils; import org.jdom.Document; import org.jdom.Element; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import com.enonic.cms.framework.xml.XMLDocument; import com.enonic.cms.framework.xml.XMLDocumentFactory; import com.enonic.cms.core.CmsDateAndTimeFormats; import com.enonic.cms.core.content.access.ContentAccessEntity; import com.enonic.cms.core.content.access.ContentAccessResolver; import com.enonic.cms.core.content.access.ContentAccessRightsAccumulated; import com.enonic.cms.core.content.access.ContentAccessXmlCreator; import com.enonic.cms.core.content.binary.BinaryDataXmlCreator; import com.enonic.cms.core.content.category.CategoryAccessResolver; import com.enonic.cms.core.content.category.CategoryAccessRightsAccumulated; import com.enonic.cms.core.content.category.CategoryEntity; import com.enonic.cms.core.content.category.UnitEntity; import com.enonic.cms.core.content.contenttype.ContentTypeEntity; import com.enonic.cms.core.content.resultset.ContentResultSet; import com.enonic.cms.core.content.resultset.RelatedContent; import com.enonic.cms.core.content.resultset.RelatedContentResultSet; import com.enonic.cms.core.language.LanguageEntity; import com.enonic.cms.core.language.LanguageKey; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.security.userstore.UserStoreEntity; import com.enonic.cms.core.structure.menuitem.section.SectionContentXmlCreator; public class ContentXMLCreator { private static final DateTimeFormatter VERSIONS_DATETIME_FORMAT = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss.S" ); public static final String DEFAULT_RESULTROOTNAME = "contents"; private CategoryAccessResolver categoryAccessResolver; private ContentAccessResolver contentAccessResolver; private BinaryDataXmlCreator binaryDataXmlCreator = new BinaryDataXmlCreator(); private SectionContentXmlCreator sectionContentXmlCreator = new SectionContentXmlCreator(); private ContentAccessXmlCreator contentAccessXmlCreator = new ContentAccessXmlCreator(); private RelatedContentKeysXmlCreator relatedContentKeysXmlCreator; private ContentLocationXmlCreator contentLocationXmlCreator = new ContentLocationXmlCreator(); /** * The starting index of the results in the XML to be created. */ private int index = 0; /** * The length of the result set in the XML to be created. */ private int count = 1; /** * Whether or not to include related content in the resulting XML. */ private boolean includeRelatedContentsInfo = true; /** * Specify whether or not to include information about the category of the content in the generated XML. */ private boolean includeCategoryData = true; /** * Specify whether or not to include information about the owner and modifier of the content in the generated XML. */ private boolean includeOwnerAndModifierData = true; private boolean includeAssignment = false; /** * Specify whether or not to include the main content data in the generated XML. */ private boolean includeContentData = true; /** * Specify whether or not to include the main content data for related content in the generated XML. Setting this parameter to true * makes no sense, unless also <code>includeRelatedContentsInfo</code> is true. */ private boolean includeRelatedContentData = true; /** * Whether or not to include the access information on each content in the returned document. */ private boolean includeAccessRightsInfo = false; /** * Whether or not to include the user rights information for the given content. */ private boolean includeUserRightsInfo = false; /** * Whether or not to include versions information for the given content in a minimal format suited for the admin GUI. * <p/> * This value can not be true at the same time as <code>includeVersionsInfoForPortal</code> or <code>includeVersionsInfoForClient</code> * is true. */ private boolean includeVersionsInfoForAdmin = false; /** * Whether or not to include a list of versions for the content, in a format that is suitable for template developers using the data * sources. This means that versions of status 2 or 3 will be included in the result. * <p/> * This value can not be true at the same time as <code>includeVersionsInfoForAdmin</code> or <code>includeVersionsInfoForClient</code> * is true. */ private boolean includeVersionsInfoForPortal = false; /** * Whether or not to include a list of versions for the content, in a format that is suitable for template developers using the data * sources. This means that versions of any status will be included in the result. * <p/> * This value can not be true at the same time as <code>includeVersionsInfoForAdmin</code> or <code>includeVersionsInfoForPortal</code> * is true. */ private boolean includeVersionsInfoForClient = false; private Date onlineCheckDate = new Date(); private boolean includeRepositoryPathInfo = false; private boolean includeSectionActivationInfo = false; private boolean includeUserRightsInfoForRelated = false; private boolean orderByCreatedAtDescending = false; private boolean includeDraftInfo = false; private static final String ASSIGNMENT_DUEDATE_XML_KEY = "assignment-due-date"; private static final String ASSIGNEE_XML_KEY = "assignee"; private static final String ASSIGNER_XML_KEY = "assigner"; private static final String ASSIGNMENT_DESCRIPTION_XML_KEY = "assignment-description"; private static final String COMMENT_XML_KEY = "comment"; private ContentPublishedResolver publishedResolver; public ContentXMLCreator() { // nothing } public Element createSingleContentVersionElement( UserEntity runningUser, ContentVersionEntity version ) { ContentEntity content = version.getContent(); return doCreateContentElement( content, version, runningUser, includeContentData, false ); } public Element createContentElement( UserEntity runningUser, ContentAndVersion contentAndVersion ) { return doCreateContentElement( contentAndVersion.getContent(), contentAndVersion.getVersion(), runningUser, includeContentData, false ); } public XMLDocument createContentVersionsDocument( UserEntity user, Collection<ContentVersionEntity> versions, RelatedContentResultSet children ) { if ( versions == null ) { throw new IllegalArgumentException( "Given versions cannot be null" ); } Element contentsElement = createContentsElement(); relatedContentKeysXmlCreator = new RelatedContentKeysXmlCreator( children ); for ( ContentVersionEntity version : versions ) { Element contentElement = doCreateContentElement( version.getContent(), version, user, includeContentData, false ); contentElement.addContent( relatedContentKeysXmlCreator.createForContent( version ) ); contentsElement.addContent( contentElement ); } if ( includeRelatedContentsInfo ) { contentsElement.addContent( doCreateRelatedContentsElement( user, children ) ); } return XMLDocumentFactory.create( new Document( contentsElement ) ); } public XMLDocument createContentsDocument( final UserEntity runningUser, final ContentVersionEntity version, final RelatedContentResultSet relatedContents ) { final Element contentsEl = createContentsElement(); final ContentEntity content = version.getContent(); final Element contentEl = doCreateContentElement( content, version, runningUser, includeContentData, false ); contentsEl.addContent( contentEl ); if ( includeRelatedContentsInfo && relatedContents != null ) { relatedContentKeysXmlCreator = new RelatedContentKeysXmlCreator( relatedContents ); contentEl.addContent( relatedContentKeysXmlCreator.createForContent( version ) ); Element relatedContentsEl = new Element( "relatedcontents" ); relatedContentsEl.setAttribute( "count", Integer.toString( relatedContents.size() ) ); contentsEl.addContent( doCreateRelatedContentsElement( runningUser, relatedContents ) ); } return XMLDocumentFactory.create( new Document( contentsEl ) ); } public XMLDocument createContentsDocument( UserEntity user, ContentResultSet contentResultSet, RelatedContentResultSet relatedContents ) { if ( contentResultSet == null ) { throw new IllegalArgumentException( "The ContentResultSet argument may not be NULL" ); } if ( relatedContents == null ) { throw new IllegalArgumentException( "The RelatedContentResultSet argument may not be NULL" ); } if ( contentResultSet.hasErrors() ) { return doCreateErrorDocument( contentResultSet.getErrors(), index, count ); } relatedContentKeysXmlCreator = new RelatedContentKeysXmlCreator( relatedContents ); final Element contentsEl = createContentsElement(); for ( int i = 0; i < contentResultSet.getLength(); i++ ) { final ContentEntity content = contentResultSet.getContent( i ); if ( content == null ) { throw new IllegalArgumentException( "Content with key: " + contentResultSet.getKey( i ) + " not found" ); } final Element contentEl = doCreateContentElement( content, content.getMainVersion(), user, includeContentData, false ); contentEl.addContent( relatedContentKeysXmlCreator.createForContent( content.getMainVersion() ) ); contentsEl.addContent( contentEl ); } contentsEl.setAttribute( "totalcount", Integer.toString( contentResultSet.getTotalCount() ) ); // searchcount is deprecated, since it is the same as totalCount - to be removed some beautiful day // (jvs@2008-07-01) contentsEl.setAttribute( "searchcount", Integer.toString( contentResultSet.getTotalCount() ) ); contentsEl.setAttribute( "index", Integer.toString( index ) ); contentsEl.setAttribute( "count", Integer.toString( count ) ); contentsEl.setAttribute( "resultcount", Integer.toString( contentResultSet.getLength() ) ); if ( includeRelatedContentsInfo ) { final Element relatedContentsElement = doCreateRelatedContentsElement( user, relatedContents ); contentsEl.addContent( relatedContentsElement ); } return XMLDocumentFactory.create( new Document( contentsEl ) ); } public XMLDocument createContentVersionsDocument( UserEntity user, ContentResultSet contentResultSet, RelatedContentResultSet relatedContents ) { if ( contentResultSet == null ) { throw new IllegalArgumentException( "The contentResultSet argument may not be NULL" ); } if ( relatedContents == null ) { throw new IllegalArgumentException( "The contentResultSet argument may not be NULL" ); } if ( contentResultSet.hasErrors() ) { return doCreateErrorDocument( contentResultSet.getErrors(), index, count ); } relatedContentKeysXmlCreator = new RelatedContentKeysXmlCreator( relatedContents ); final Element contentsEl = createContentsElement(); for ( int i = 0; i < contentResultSet.getLength(); i++ ) { final ContentEntity content = contentResultSet.getContent( i ); ContentVersionEntity contentVersion; contentVersion = content.getMainVersion(); final Element contentEl = doCreateContentElement( content, contentVersion, user, includeContentData, false ); contentEl.addContent( relatedContentKeysXmlCreator.createForContent( contentVersion ) ); contentsEl.addContent( contentEl ); } contentsEl.setAttribute( "totalcount", Integer.toString( contentResultSet.getTotalCount() ) ); // searchcount is deprecated, since it is the same as totalCount - to be removed some beautiful day // (jvs@2008-07-01) contentsEl.setAttribute( "searchcount", Integer.toString( contentResultSet.getTotalCount() ) ); contentsEl.setAttribute( "index", Integer.toString( index ) ); contentsEl.setAttribute( "count", Integer.toString( count ) ); contentsEl.setAttribute( "resultcount", Integer.toString( contentResultSet.getLength() ) ); if ( includeRelatedContentsInfo ) { final Element relatedContentsElement = doCreateRelatedContentsElement( user, relatedContents ); contentsEl.addContent( relatedContentsElement ); } return XMLDocumentFactory.create( new Document( contentsEl ) ); } public XMLDocument createEmptyDocument( String message ) { Element root = createContentsElement(); Document doc = new Document( root ); root.setAttribute( "totalcount", "0" ); if ( ( message != null ) && ( message.length() > 0 ) ) { root.setAttribute( "message", message ); } return XMLDocumentFactory.create( doc ); } private Element createContentsElement() { return new Element( DEFAULT_RESULTROOTNAME ); } private XMLDocument doCreateErrorDocument( Collection<String> errors, int index, int count ) { Element root = createContentsElement(); root.setAttribute( "index", String.valueOf( index ) ); root.setAttribute( "count", String.valueOf( count ) ); Document doc = new Document( root ); Element errorsEl = new Element( "_errors" ); root.addContent( errorsEl ); for ( String error : errors ) { Element errorEl = new Element( "_error" ); String messageWithoutLineBreaks = error.replaceAll( "\n", " " ); errorEl.setAttribute( "message", messageWithoutLineBreaks ); errorsEl.addContent( errorEl ); } return XMLDocumentFactory.create( doc ); } private Element doCreateRelatedContentsElement( final UserEntity user, final RelatedContentResultSet relatedContents ) { final Element relatedContentsEl = new Element( "relatedcontents" ); if ( !relatedContents.isEmpty() ) { final Collection<RelatedContent> relatedContentCollection = relatedContents.getDistinctCollectionOfRelatedContent(); for ( final RelatedContent relatedContent : relatedContentCollection ) { final Element el = doCreateRelatedContentElement( relatedContent, user ); relatedContentsEl.addContent( el ); } } relatedContentsEl.setAttribute( "count", String.valueOf( relatedContents.size() ) ); return relatedContentsEl; } private Element doCreateRelatedContentElement( final RelatedContent relatedContent, final UserEntity user ) { final ContentEntity content = relatedContent.getContent(); final ContentVersionEntity version = content.getMainVersion(); Element contentEl = doCreateContentElement( content, version, user, includeRelatedContentData, true ); contentEl.addContent( relatedContentKeysXmlCreator.createForRelatedContent( relatedContent ) ); return contentEl; } private Element doCreateContentElement( final ContentEntity content, final ContentVersionEntity contentVersion, final UserEntity user, final boolean includeContentData, final boolean isRelatedContent ) { final CategoryEntity category = content.getCategory(); final UnitEntity unit = category.getUnitExcludeDeleted(); final ContentTypeEntity contentType = category.getContentType(); final LanguageEntity language = content.getLanguage(); Element contentEl = new Element( "content" ); contentEl.setAttribute( "unitkey", unit.getKey().toString() ); contentEl.setAttribute( "approved", Boolean.toString( contentVersion.isApproved() ) ); contentEl.setAttribute( "state", Integer.toString( contentVersion.getState( onlineCheckDate ) ) ); contentEl.setAttribute( "status", Integer.toString( contentVersion.getStatus().getKey() ) ); contentEl.setAttribute( "published", computePublishingInSection( content ) ); contentEl.setAttribute( "contenttype", contentType.getName() ); contentEl.setAttribute( "contenttypekey", Integer.toString( contentType.getKey() ) ); contentEl.setAttribute( "created", CmsDateAndTimeFormats.printAs_XML_DATE( content.getCreatedAt() ) ); contentEl.setAttribute( "key", content.getKey().toString() ); if ( includeDraftInfo ) { contentEl.setAttribute( "has-draft", Boolean.toString( content.hasDraft() ) ); contentEl.setAttribute( "draft-key", content.hasDraft() ? content.getDraftVersion().getKey().toString() : "" ); } if ( includeVersionsInfoForAdmin || includeVersionsInfoForClient || includeVersionsInfoForPortal ) { contentEl.setAttribute( "versionkey", String.valueOf( contentVersion.getKey() ) ); contentEl.setAttribute( "current", Boolean.toString( contentVersion.isMainVersion() ) ); } contentEl.setAttribute( "languagecode", language.getCode() ); LanguageKey languageKey = language.getKey(); contentEl.setAttribute( "languagekey", languageKey.toString() ); contentEl.setAttribute( "priority", Integer.toString( content.getPriority() ) ); setDateAttributeConditional( contentEl, "publishfrom", content.getAvailableFrom() ); setDateAttributeConditional( contentEl, "publishto", content.getAvailableTo() ); setDateAttributeConditional( contentEl, "timestamp", contentVersion.getModifiedAt() ); if ( includeOwnerAndModifierData ) { addOwnerAndModifier( content, contentVersion, contentEl ); } if ( includeAssignment ) { contentEl.setAttribute( "is-assigned", Boolean.toString( content.isAssigned() ) ); addAssignee( content, contentEl ); addAssigner( content, contentEl ); addAssignmentDueDate( content, contentEl ); addAssignmentDescription( content, contentEl ); } contentEl.addContent( new Element( "name" ).addContent( content.getName() ) ); final String contentVersionTitle = contentVersion.getTitle(); final Element titleEl = new Element( "title" ); titleEl.setAttribute( "deprecated", "Use display-name instead" ); titleEl.addContent( contentVersionTitle ); contentEl.addContent( titleEl ); contentEl.addContent( new Element( "display-name" ).addContent( contentVersionTitle ) ); if ( includeContentData ) { contentEl.addContent( createElement( contentVersion.getContentDataAsJDomDocument() ) ); } if ( includeCategoryData ) { addCategoryData( category, contentEl ); } final Element locationElement = contentLocationXmlCreator.createLocationElement( content, includeSectionActivationInfo ); contentEl.addContent( locationElement ); final Element sectionNamesEl = sectionContentXmlCreator.createSectionNamesElement( content, includeSectionActivationInfo ); contentEl.addContent( sectionNamesEl ); final Element binariesEl = binaryDataXmlCreator.createBinariesElement( contentVersion ); contentEl.addContent( binariesEl ); if ( includeAccessRightsInfo && !isRelatedContent ) { addAccessRightsInfo( content, contentEl ); } if ( includeUserRightsInfo && !isRelatedContent ) { addUserRightsInfo( content, user, contentEl ); } if ( includeUserRightsInfoForRelated && isRelatedContent ) { addUserRightsInfo( content, user, contentEl ); } if ( includeVersionsInfoForAdmin && !isRelatedContent ) { final Element versionsEl = doCreateVersionsElementForAdmin( content ); contentEl.addContent( versionsEl ); } if ( ( includeVersionsInfoForPortal || includeVersionsInfoForClient ) && !isRelatedContent ) { final Element versionsEl = doCreateVersionsElementForPortal( content ); contentEl.addContent( versionsEl ); } if ( includeRepositoryPathInfo ) { contentEl.setAttribute( "repositorypath", content.getCategory().getPathAsString() ); } return contentEl; } public void setPublishedResolver( final ContentPublishedResolver publishedResolver ) { this.publishedResolver = publishedResolver; } private ContentPublishedResolver getPublishedResolver() { if ( publishedResolver == null ) { publishedResolver = new ContentPublishedResolver(); } return publishedResolver; } /** * Compute if the content has been added to one (or more) sections, and if it is published or not in these sections. * @param content observed content * @return * - 'published' when content is in one or more sections and published in at least one of them * - 'unpublished' when content is in one or more sections, but not published in any of them * - 'none' when the content is not in any section */ private String computePublishingInSection( final ContentEntity content ) { return getPublishedResolver().computePublishingInSection( content ); } private void addAssigner( ContentEntity content, Element contentEl ) { Element assigner = new Element( ASSIGNER_XML_KEY ); if ( content.getAssigner() != null ) { addUserData( assigner, content.getAssigner() ); } contentEl.addContent( assigner ); } private void addAssignmentDescription( ContentEntity content, Element contentEl ) { String assignmentDescription = StringUtils.isEmpty( content.getAssignmentDescription() ) ? "" : content.getAssignmentDescription(); contentEl.addContent( new Element( ASSIGNMENT_DESCRIPTION_XML_KEY ).addContent( assignmentDescription ) ); } private void addUserRightsInfo( ContentEntity content, UserEntity user, Element contentEl ) { final Element userRightEl = doCreateUserRightElement( content, user ); contentEl.addContent( userRightEl ); } private void addAccessRightsInfo( ContentEntity content, Element contentEl ) { final Collection<ContentAccessEntity> accessEntities = content.getContentAccessRights(); final Element contentAccessRightsEl = contentAccessXmlCreator.createAccessRightsElement( accessEntities ); contentEl.addContent( contentAccessRightsEl ); } private void addCategoryData( CategoryEntity category, Element contentEl ) { final Element categoryNameEl = new Element( "categoryname" ); categoryNameEl.setAttribute( "key", category.getKey().toString() ); categoryNameEl.setAttribute( "deprecated", "Use category instead" ); categoryNameEl.setText( category.getName() ); contentEl.addContent( categoryNameEl ); contentEl.addContent( doCreateCategoryElement( category ) ); } private void addOwnerAndModifier( ContentEntity content, ContentVersionEntity contentVersion, Element contentEl ) { Element owner = new Element( "owner" ); addUserData( owner, content.getOwner() ); contentEl.addContent( owner ); Element modifier = new Element( "modifier" ); addUserData( modifier, contentVersion.getModifiedBy() ); contentEl.addContent( modifier ); } private void addAssignee( ContentEntity content, Element contentEl ) { Element assignee = new Element( ASSIGNEE_XML_KEY ); if ( content.getAssignee() != null ) { addUserData( assignee, content.getAssignee() ); } contentEl.addContent( assignee ); } private void addAssignmentDueDate( ContentEntity content, Element contentEl ) { Element dueDate = new Element( ASSIGNMENT_DUEDATE_XML_KEY ); if ( content.getAssignmentDueDate() != null ) { dueDate.setAttribute( "is-overdue", Boolean.toString( content.isAssignmentOverdue() ) ); dueDate.addContent( CmsDateAndTimeFormats.printAs_XML_DATE( content.getAssignmentDueDate() ) ); } contentEl.addContent( dueDate ); } private Element doCreateVersionsElementForAdmin( ContentEntity content ) { final Element versionsEl = new Element( "versions" ); List<ContentVersionEntity> allVersions = new ArrayList<ContentVersionEntity>( content.getVersions() ); if ( orderByCreatedAtDescending ) { Collections.sort( allVersions, new ContentVersionCreatedAtDescendingComparator() ); } for ( ContentVersionEntity version : allVersions ) { final Element versionEl = new Element( "version" ); final UserEntity modifier = version.getModifiedBy(); versionEl.setAttribute( "key", String.valueOf( version.getKey() ) ); versionEl.setAttribute( "created", VERSIONS_DATETIME_FORMAT.print( version.getCreatedAt().getTime() ) ); versionEl.setAttribute( "timestamp", VERSIONS_DATETIME_FORMAT.print( version.getModifiedAt().getTime() ) ); versionEl.setAttribute( "modified", VERSIONS_DATETIME_FORMAT.print( version.getModifiedAt().getTime() ) ); versionEl.setAttribute( "modifierFullName", modifier.getDisplayName() ); versionEl.setAttribute( "modifierQualifiedName", modifier.getQualifiedName().toString() ); versionEl.setAttribute( "title", version.getTitle() ); versionEl.setAttribute( "status", String.valueOf( version.getStatus().getKey() ) ); versionEl.setAttribute( "state", String.valueOf( version.getState( onlineCheckDate ) ) ); versionEl.setAttribute( "current", Boolean.toString( version.isMainVersion() ) ); versionEl.setAttribute( "snapshotSource", version.getSnapshotSource() == null ? "" : version.getSnapshotSource().getKey().toString() ); versionEl.setAttribute( COMMENT_XML_KEY, StringUtils.isBlank( version.getChangeComment() ) ? "" : version.getChangeComment() ); versionsEl.addContent( versionEl ); } return versionsEl; } private Element doCreateVersionsElementForPortal( final ContentEntity content ) { final Element versionsEl = new Element( "versions" ); final List<ContentVersionEntity> versions = new ArrayList<ContentVersionEntity>( content.getVersionCount() ); for ( ContentVersionEntity version : content.getVersions() ) { versions.add( version ); } Collections.sort( versions, new ContentVersionComparator() ); for ( ContentVersionEntity version : versions ) { if ( includeVersionsInfoForClient || version.isApproved() || version.isArchived() ) { createSpecificVersionElement( version, versionsEl ); } } return versionsEl; } private void createSpecificVersionElement( ContentVersionEntity version, Element statusElement ) { final Element versionElement = new Element( "version" ); versionElement.setAttribute( "key", String.valueOf( version.getKey() ) ); versionElement.setAttribute( "status-key", String.valueOf( version.getStatus().getKey() ) ); versionElement.setAttribute( "status", version.getStatusName() ); versionElement.setAttribute( "timestamp", VERSIONS_DATETIME_FORMAT.print( version.getModifiedAt().getTime() ) ); if ( version.isMainVersion() ) { versionElement.setAttribute( "current", "true" ); } Element titleElement = new Element( "title" ); titleElement.setText( version.getTitle() ); versionElement.addContent( titleElement ); Element modifierElement = new Element( "modifier" ); addUserData( modifierElement, version.getModifiedBy() ); versionElement.addContent( modifierElement ); Element commentElement = new Element( COMMENT_XML_KEY ); commentElement.setText( version.getChangeComment() ); versionElement.addContent( commentElement ); statusElement.addContent( versionElement ); } /** * If the given date is a valid date, it is set as an attribute in the content, overriding any previous values if they exist. If the * given date is not valid, no changes are performed. * * @param content The Element of which to add this attribute. * @param attribute The name of the attribute. * @param d The date containing the value to set. */ private static void setDateAttributeConditional( Element content, String attribute, Date d ) { if ( d != null ) { content.setAttribute( attribute, CmsDateAndTimeFormats.printAs_XML_DATE( d ) ); } } private static void addUserData( Element elem, UserEntity user ) { elem.setAttribute( "key", user.getKey().toString() ); elem.setAttribute( "deleted", Boolean.toString( user.isDeleted() ) ); elem.setAttribute( "qualified-name", user.getQualifiedName().toString() ); UserStoreEntity userStore = user.getUserStore(); if ( userStore != null ) { elem.addContent( new Element( "userstore" ).setText( userStore.getName() ) ); } elem.addContent( new Element( "name" ).setText( user.getName() ) ); elem.addContent( new Element( "display-name" ).setText( user.getDisplayName() ) ); elem.addContent( new Element( "email" ).setText( user.getEmail() ) ); Element photo = new Element( "photo" ); photo.setAttribute( "exists", Boolean.toString( user.hasPhoto() ) ); elem.addContent( photo ); } private static Element createElement( Document doc ) { Element element = doc.getRootElement(); element.detach(); return element; } private Element doCreateUserRightElement( final ContentEntity content, final UserEntity user ) { final Element userRightEl = new Element( "userright" ); final CategoryEntity category = content.getCategory(); final CategoryAccessRightsAccumulated categoryAccess = categoryAccessResolver.getAccumulatedAccessRights( user, category ); if ( categoryAccess.isCreate() ) { userRightEl.setAttribute( "categorycreate", "true" ); } if ( categoryAccess.isPublish() ) { userRightEl.setAttribute( "categorypublish", "true" ); } if ( categoryAccess.isPublish() || categoryAccess.isAdministrate() ) { userRightEl.setAttribute( "read", "true" ); userRightEl.setAttribute( "update", "true" ); userRightEl.setAttribute( "delete", "true" ); } else { final ContentAccessRightsAccumulated contentAccess = contentAccessResolver.getAccumulatedAccessRights( user, content ); userRightEl.setAttribute( "read", Boolean.toString( contentAccess.isReadAccess() ) ); userRightEl.setAttribute( "update", Boolean.toString( contentAccess.isUpdateAccess() ) ); userRightEl.setAttribute( "delete", Boolean.toString( contentAccess.isDeleteAccess() ) ); } return userRightEl; } private static Element doCreateCategoryElement( CategoryEntity category ) { Element categoryEl = new Element( "category" ); categoryEl.setAttribute( "key", String.valueOf( category.getKey() ) ); categoryEl.setAttribute( "name", category.getName() ); return categoryEl; } private class ContentVersionCreatedAtDescendingComparator implements Comparator<ContentVersionEntity> { public int compare( ContentVersionEntity version1, ContentVersionEntity version2 ) { boolean ver1IsNewest = version1.getCreatedAt().before( version2.getCreatedAt() ); if ( ver1IsNewest ) { return 1; } else { return -1; } } } private class ContentVersionComparator implements Comparator<ContentVersionEntity> { /** * Sorts 2 <code>ContentVersionEntity</code> object such that all drafts come first, then snapshot, approved and * archived. * <p/> * If the objects have the same status, then the object that is most recently modified will be considered the least, and come * first. * * @param entity1 The first entity to compare. If this should come first, the returned value is negative. * @param entity2 The second entity to compare. If this should come first, the returned value is positive. * @return A negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the * second. */ public int compare( ContentVersionEntity entity1, ContentVersionEntity entity2 ) { if ( !entity1.getStatus().equals( entity2.getStatus() ) ) { return entity2.getStatus().getKey() - entity1.getStatus().getKey(); } if ( entity1.getModifiedAt().before( entity2.getModifiedAt() ) ) { return -1; } else if ( entity1.getModifiedAt().after( entity2.getModifiedAt() ) ) { return 1; } else { return entity1.getKey().toInt() > entity2.getKey().toInt() ? 1 : -1; } } } public void setIncludeOwnerAndModifierData( boolean value ) { includeOwnerAndModifierData = value; } public void setIncludeAssignment( boolean includeAssignment ) { this.includeAssignment = includeAssignment; } public void setIncludeContentData( boolean value ) { this.includeContentData = value; } public void setIncludeCategoryData( boolean value ) { includeCategoryData = value; } public void setIncludeRelatedContentData( boolean value ) { includeRelatedContentData = value; } public void setResultIndexing( int startingIndex, int resultLength ) { index = startingIndex; count = resultLength; } public void setIncludeUserRightsInfo( boolean value, CategoryAccessResolver categoryAccessResolver, ContentAccessResolver contentAccessResolver ) { includeUserRightsInfo = value; this.categoryAccessResolver = categoryAccessResolver; this.contentAccessResolver = contentAccessResolver; } public void setIncludeAccessRightsInfo( boolean value ) { includeAccessRightsInfo = value; } public void setIncludeVersionsInfoForAdmin( boolean value ) { includeVersionsInfoForAdmin = value; if ( includeVersionsInfoForAdmin ) { includeVersionsInfoForPortal = false; includeVersionsInfoForClient = false; } } public void setIncludeVersionsInfoForPortal( boolean value ) { includeVersionsInfoForPortal = value; if ( includeVersionsInfoForPortal ) { includeVersionsInfoForAdmin = false; includeVersionsInfoForClient = false; } } public void setIncludeVersionsInfoForClient( boolean value ) { includeVersionsInfoForClient = value; if ( includeVersionsInfoForClient ) { includeVersionsInfoForAdmin = false; includeVersionsInfoForPortal = false; } } public void setIncludeRelatedContentsInfo( boolean value ) { includeRelatedContentsInfo = value; } public void setIncludeRepositoryPathInfo( boolean includeRepositoryPathInfo ) { this.includeRepositoryPathInfo = includeRepositoryPathInfo; } public void setIncludeSectionActivationInfo( boolean includeSectionActivationInfo ) { this.includeSectionActivationInfo = includeSectionActivationInfo; } public void setOnlineCheckDate( Date onlineCheckDate ) { this.onlineCheckDate = onlineCheckDate; } public void setIncludeUserRightsInfoForRelated( final boolean includeUserRightsInfoForRelated, CategoryAccessResolver categoryAccessResolver, ContentAccessResolver contentAccessResolver ) { this.includeUserRightsInfoForRelated = includeUserRightsInfoForRelated; this.categoryAccessResolver = categoryAccessResolver; this.contentAccessResolver = contentAccessResolver; } public void setOrderByCreatedAtDescending( boolean orderByCreatedAtDescending ) { this.orderByCreatedAtDescending = orderByCreatedAtDescending; } public void setIncludeDraftInfo( boolean includeDraftInfo ) { this.includeDraftInfo = includeDraftInfo; } }