/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.client; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.jdom.Document; import org.jdom.Element; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.enonic.esl.util.Base64Util; import com.enonic.cms.framework.blob.BlobRecord; import com.enonic.cms.api.client.ClientException; import com.enonic.cms.api.client.model.AssignContentParams; import com.enonic.cms.api.client.model.ContentDataInputUpdateStrategy; import com.enonic.cms.api.client.model.CreateCategoryParams; import com.enonic.cms.api.client.model.CreateContentParams; import com.enonic.cms.api.client.model.CreateFileContentParams; import com.enonic.cms.api.client.model.CreateImageContentParams; import com.enonic.cms.api.client.model.DeleteContentParams; import com.enonic.cms.api.client.model.GenerateLowResImagesParams; import com.enonic.cms.api.client.model.GetBinaryParams; import com.enonic.cms.api.client.model.GetContentBinaryParams; import com.enonic.cms.api.client.model.MoveContentParams; import com.enonic.cms.api.client.model.SnapshotContentParams; import com.enonic.cms.api.client.model.UnassignContentParams; import com.enonic.cms.api.client.model.UpdateContentParams; import com.enonic.cms.api.client.model.UpdateFileContentParams; import com.enonic.cms.core.content.ContentEntity; import com.enonic.cms.core.content.ContentKey; import com.enonic.cms.core.content.ContentLocation; import com.enonic.cms.core.content.ContentLocationSpecification; import com.enonic.cms.core.content.ContentLocations; import com.enonic.cms.core.content.ContentService; import com.enonic.cms.core.content.ContentStatus; import com.enonic.cms.core.content.ContentVersionEntity; import com.enonic.cms.core.content.ContentVersionKey; import com.enonic.cms.core.content.PageCacheInvalidatorForContent; import com.enonic.cms.core.content.UpdateContentResult; import com.enonic.cms.core.content.access.ContentAccessResolver; import com.enonic.cms.core.content.access.ContentAccessType; import com.enonic.cms.core.content.binary.AttachmentNotFoundException; import com.enonic.cms.core.content.binary.BinaryData; import com.enonic.cms.core.content.binary.BinaryDataAndBinary; import com.enonic.cms.core.content.binary.BinaryDataEntity; import com.enonic.cms.core.content.binary.BinaryDataKey; import com.enonic.cms.core.content.binary.ContentBinaryDataEntity; import com.enonic.cms.core.content.category.CategoryAccessResolver; import com.enonic.cms.core.content.category.CategoryAccessType; import com.enonic.cms.core.content.category.CategoryEntity; import com.enonic.cms.core.content.category.CategoryKey; import com.enonic.cms.core.content.category.CategoryService; import com.enonic.cms.core.content.category.StoreNewCategoryCommand; import com.enonic.cms.core.content.command.AssignContentCommand; import com.enonic.cms.core.content.command.CreateContentCommand; import com.enonic.cms.core.content.command.SnapshotContentCommand; import com.enonic.cms.core.content.command.UnassignContentCommand; import com.enonic.cms.core.content.command.UpdateContentCommand; import com.enonic.cms.core.content.command.UpdateContentCommand.UpdateStrategy; import com.enonic.cms.core.content.contentdata.custom.BinaryDataEntry; import com.enonic.cms.core.content.contentdata.custom.CustomContentData; import com.enonic.cms.core.content.contentdata.legacy.LegacyFileContentData; import com.enonic.cms.core.content.contentdata.legacy.LegacyImageContentData; import com.enonic.cms.core.content.contenttype.ContentTypeEntity; import com.enonic.cms.core.content.contenttype.ContentTypeKey; import com.enonic.cms.core.content.image.ContentImageUtil; import com.enonic.cms.core.content.image.GenerateLowResImagesCommand; import com.enonic.cms.core.content.image.ImageUtil; import com.enonic.cms.core.portal.PrettyPathNameCreator; import com.enonic.cms.core.portal.cache.PageCache; import com.enonic.cms.core.portal.cache.PageCacheService; import com.enonic.cms.core.preview.PreviewContext; import com.enonic.cms.core.preview.PreviewService; import com.enonic.cms.core.security.SecurityService; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.security.user.UserParser; import com.enonic.cms.core.security.userstore.UserStoreParser; import com.enonic.cms.core.security.userstore.UserStoreService; import com.enonic.cms.core.structure.SiteKey; import com.enonic.cms.core.time.TimeService; import com.enonic.cms.store.dao.BinaryDataDao; import com.enonic.cms.store.dao.CategoryDao; import com.enonic.cms.store.dao.ContentBinaryDataDao; import com.enonic.cms.store.dao.ContentDao; import com.enonic.cms.store.dao.ContentTypeDao; import com.enonic.cms.store.dao.ContentVersionDao; import com.enonic.cms.store.dao.GroupDao; import com.enonic.cms.store.dao.UserDao; import com.enonic.cms.store.dao.UserStoreDao; @Component public class InternalClientContentService { @Autowired private SecurityService securityService; @Autowired private UserStoreService userStoreService; @Autowired private ContentService contentService; @Autowired private ContentTypeDao contentTypeDao; @Autowired private ContentDao contentDao; @Autowired private BinaryDataDao binaryDataDao; @Autowired private ContentBinaryDataDao contentBinaryDataDao; @Autowired private ContentVersionDao contentVersionDao; @Autowired private CategoryDao categoryDao; @Autowired private GroupDao groupDao; @Autowired private UserDao userDao; @Autowired private UserStoreDao userStoreDao; @Autowired private PreviewService previewService; @Autowired private TimeService timeService; @Autowired private PageCacheService pageCacheService; private FileContentdataResolver fileContentResolver = new FileContentdataResolver(); private ImageContentdataResolver imageContentResolver = new ImageContentdataResolver(); @Autowired private CategoryService categoryService; @Value("${cms.name.transliterate}") private boolean transliterate; public int createCategory( CreateCategoryParams params ) { if ( params.contentTypeKey != null && params.contentTypeName != null ) { throw new ClientException( "Specify content type by either key or name, not both" ); } if ( params.parentCategoryKey == null ) { throw new ClientException( "The parent category must be set" ); } CategoryEntity parentCategory = categoryDao.findByKey( new CategoryKey( params.parentCategoryKey ) ); if ( parentCategory == null ) { throw new ClientException( "The parent category does not exist" ); } UserEntity runningUser = securityService.getImpersonatedPortalUser(); CategoryAccessResolver categoryAccessResolver = new CategoryAccessResolver( groupDao ); if ( !categoryAccessResolver.hasAccess( runningUser, parentCategory, CategoryAccessType.ADMINISTRATE ) ) { throw new ClientException( "The currently logged in user does not have create access on the category" ); } ContentTypeKey contentTypeKey = null; if ( params.contentTypeKey != null ) { contentTypeKey = new ContentTypeKey( params.contentTypeKey ); } else if ( params.contentTypeName != null ) { ContentTypeEntity contentType = contentTypeDao.findByName( params.contentTypeName ); if ( contentType == null ) { throw new ClientException( "Specified content type by name '" + params.contentTypeName + "' does not exist" ); } contentTypeKey = contentType.getContentTypeKey(); } final StoreNewCategoryCommand command = new StoreNewCategoryCommand(); command.setCreator( runningUser.getKey() ); command.setName( params.name ); command.setParentCategory( new CategoryKey( params.parentCategoryKey ) ); command.setContentType( contentTypeKey ); command.setAutoApprove( params.autoApprove ); final CategoryKey newCategoryKey = categoryService.storeNewCategory( command ); return newCategoryKey.toInt(); } public void deleteContent( DeleteContentParams params ) { UserEntity runningUser = securityService.getImpersonatedPortalUser(); ContentEntity content = contentDao.findByKey( new ContentKey( params.contentKey ) ); if ( content != null && !content.isDeleted() ) { ContentLocationSpecification contentLocationSpecification = new ContentLocationSpecification(); contentLocationSpecification.setIncludeInactiveLocationsInSection( false ); ContentLocations contentLocations = content.getLocations( contentLocationSpecification ); contentService.deleteContent( runningUser, content, params.siteKey != null ? new SiteKey( params.siteKey ) : null ); for ( ContentLocation contentLocation : contentLocations.getAllLocations() ) { PageCache pageCache = pageCacheService.getPageCacheService( contentLocation.getSiteKey() ); pageCache.removeEntriesByMenuItem( contentLocation.getMenuItemKey() ); } } } public int createContent( CreateContentParams params ) throws ClientException { final CategoryEntity category = validateCreateContentParams( params ); final CreateContentCommand command = new CreateContentCommand(); command.setPriority( 0 ); command.setAvailableFrom( params.publishFrom ); command.setAvailableTo( params.publishTo ); command.setCategory( category ); command.setLanguage( category.getUnitExcludeDeleted().getLanguage() ); command.setStatus( ContentStatus.get( params.status ) ); command.setChangeComment( params.changeComment ); // content data final ContentTypeEntity contentType = category.getContentType(); if ( contentType == null ) { throw new IllegalArgumentException( "Unable to create content in category " + category.getKey() + ". Category has no contenttype set." ); } final ContentDataResolver customContentResolver = new ContentDataResolver(); final CustomContentData contentdata = customContentResolver.resolveContentdata( params.contentData, contentType ); command.setContentData( contentdata ); command.setContentName( new PrettyPathNameCreator( transliterate ).generatePrettyPathName( contentdata.getTitle() ) ); final List<BinaryDataAndBinary> binaryDatas = BinaryDataAndBinary.convertFromBinaryInputs( params.contentData.getBinaryInputs() ); command.setBinaryDatas( binaryDatas ); command.setUseCommandsBinaryDataToAdd( true ); command.setAccessRightsStrategy( CreateContentCommand.AccessRightsStrategy.INHERIT_FROM_CATEGORY ); command.setCreator( securityService.getImpersonatedPortalUser() ); if ( params.siteKey != null ) { command.setSiteKey( new SiteKey( params.siteKey ) ); } return contentService.createContent( command ).toInt(); } public int createImageContent( CreateImageContentParams params ) throws IOException { validateCreateImageContentParams( params ); CategoryEntity category = categoryDao.findByKey( new CategoryKey( params.categoryKey ) ); UserEntity runningUser = securityService.getImpersonatedPortalUser(); LegacyImageContentData contentdata = (LegacyImageContentData) imageContentResolver.resolveContentdata( params.contentData ); BinaryData[] binaryArray = getBinaries( params ); List<BinaryDataAndBinary> binaryDatas = BinaryDataAndBinary.createNewFrom( binaryArray ); CreateContentCommand createCommand = new CreateContentCommand(); createCommand.setAccessRightsStrategy( CreateContentCommand.AccessRightsStrategy.INHERIT_FROM_CATEGORY ); createCommand.setCreator( runningUser ); createCommand.setStatus( ContentStatus.get( params.status ) ); createCommand.setPriority( 0 ); createCommand.setCategory( category ); createCommand.setLanguage( category.getUnitExcludeDeleted().getLanguage() ); createCommand.setAvailableFrom( params.publishFrom ); createCommand.setAvailableTo( params.publishTo ); createCommand.setContentData( contentdata ); createCommand.setContentName( new PrettyPathNameCreator( transliterate ).generatePrettyPathName( contentdata.getTitle() ) ); createCommand.setChangeComment( params.changeComment ); createCommand.setBinaryDatas( binaryDatas ); createCommand.setUseCommandsBinaryDataToAdd( true ); if ( params.siteKey != null ) { createCommand.setSiteKey( new SiteKey( params.siteKey ) ); } ContentKey contentKey = contentService.createContent( createCommand ); return contentKey.toInt(); } public Document getBinary( GetBinaryParams params ) throws Exception { assertMinValue( "binaryKey", params.binaryKey, 0 ); final UserEntity runAsUser = securityService.getImpersonatedPortalUser(); final BinaryDataKey binaryDataKey = new BinaryDataKey( params.binaryKey ); final BinaryDataEntity binaryData = binaryDataDao.findByKey( binaryDataKey ); if ( binaryData == null ) { throw AttachmentNotFoundException.notFound( binaryDataKey ); } final ContentBinaryDataEntity contentBinaryDataInMainVersion = ContentBinaryDataEntity.resolveContentBinaryDataInMainVersion( contentBinaryDataDao.findAllByBinaryKey( binaryData.getKey() ) ); if ( contentBinaryDataInMainVersion == null ) { throw AttachmentNotFoundException.notFound( binaryData.getBinaryDataKey() ); } final ContentEntity content = contentBinaryDataInMainVersion.getContentVersion().getContent(); if ( content == null || content.isDeleted() ) { throw AttachmentNotFoundException.notFound( binaryDataKey ); } if ( !new ContentAccessResolver( groupDao ).hasReadContentAccess( runAsUser, content ) ) { throw AttachmentNotFoundException.noAccess( content.getKey() ); } checkContentIsOnline( content ); return createBinaryDocument( createBinaryData( contentBinaryDataInMainVersion ) ); } public Document getContentBinary( GetContentBinaryParams params ) throws ClientException { assertMinValue( "contentKey", params.contentKey, 0 ); final UserEntity runAsUser = securityService.getImpersonatedPortalUser(); final ContentKey contentKey = new ContentKey( params.contentKey ); final ContentEntity content = contentDao.findByKey( contentKey ); if ( content == null || content.isDeleted() ) { throw AttachmentNotFoundException.notFound( contentKey ); } if ( !new ContentAccessResolver( groupDao ).hasReadContentAccess( runAsUser, content ) ) { throw AttachmentNotFoundException.noAccess( content.getKey() ); } if (!params.includeOfflineContent) { checkContentIsOnline( content ); } ContentBinaryDataEntity contentBinaryData; if ( params.label == null ) { contentBinaryData = content.getMainVersion().getContentBinaryData( "source" ); if ( contentBinaryData == null ) { contentBinaryData = content.getMainVersion().getOneAndOnlyContentBinaryData(); } } else { contentBinaryData = content.getMainVersion().getContentBinaryData( params.label ); } if ( contentBinaryData == null ) { throw AttachmentNotFoundException.notFound( contentKey ); } return createBinaryDocument( createBinaryData( contentBinaryData ) ); } private BinaryData[] getBinaries( CreateImageContentParams params ) throws IOException { String binaryName = params.contentData.binary.getBinaryName(); // find file type String type = null; String filenameWithoutExtension = binaryName; int idx = binaryName.lastIndexOf( "." ); if ( idx != -1 ) { type = binaryName.substring( idx + 1 ).toLowerCase(); if ( "jpg".equals( type ) ) { type = "jpeg"; } filenameWithoutExtension = binaryName.substring( 0, idx ); } BufferedImage origImage = ImageUtil.readImage( params.contentData.binary.getBinary() ); ArrayList<BinaryData> binaryList = new ArrayList<BinaryData>(); // Do not add original as un-labeled image with name = name-heightXwitdth // Add fixed size images binaryList.addAll( ContentImageUtil.createStandardSizeImages( origImage, ContentImageUtil.getEncodeType( type ), filenameWithoutExtension ) ); // add source image BinaryData image = BinaryData.createBinaryDataFromStream( null, null, "source", params.contentData ); binaryList.add( image ); return binaryList.toArray( new BinaryData[binaryList.size()] ); } public void assignContent( AssignContentParams params ) { final UserEntity assigner = securityService.getImpersonatedPortalUser(); final UserParser userParser = new UserParser( securityService, userStoreService, userDao, new UserStoreParser( userStoreDao ) ); final UserEntity assignee = userParser.parseUser( params.assignee ); final ContentKey contentToAssignOn = new ContentKey( params.contentKey ); AssignContentCommand command = new AssignContentCommand(); command.setContentKey( contentToAssignOn ); command.setAssignerKey( assigner.getKey() ); command.setAssigneeKey( assignee.getKey() ); command.setAssignmentDueDate( params.assignmentDueDate ); command.setAssignmentDescription( params.assignmentDescription ); contentService.assignContent( command ); } public void unassignContent( UnassignContentParams params ) { final UserEntity unassigner = securityService.getImpersonatedPortalUser(); UnassignContentCommand command = new UnassignContentCommand(); command.setContentKey( new ContentKey( params.contentKey ) ); command.setUnassigner( unassigner.getKey() ); contentService.unassignContent( command ); } public void snapshotContent( SnapshotContentParams params ) { final UserEntity modifier = securityService.getImpersonatedPortalUser(); SnapshotContentCommand snapshotCommand = new SnapshotContentCommand(); snapshotCommand.setSnapshotComment( params.snapshotComment ); snapshotCommand.setSnapshotterKey( modifier.getKey() ); snapshotCommand.setContentKey( new ContentKey( params.contentKey ) ); snapshotCommand.setClearCommentInDraft( params.clearCommentInDraft ); contentService.snapshotContent( snapshotCommand ); } public int generateLowResImages( final GenerateLowResImagesParams params ) { final UserEntity modifier = securityService.getImpersonatedPortalUser(); GenerateLowResImagesCommand generateCommand = new GenerateLowResImagesCommand(); generateCommand.setCategoryKeys( params.categoryKeys ); generateCommand.setImageSize( params.imageSize ); generateCommand.setModifier( modifier ); return contentService.generateLowResImages( generateCommand ); } public int updateContent( UpdateContentParams params ) { validateUpdateContentParams( params ); final ContentVersionKey contentVersionKey = resolveContentVersionKey( params.createNewVersion, params.contentKey, params.contentVersionKey ); UpdateContentCommand command; if ( params.createNewVersion ) { command = UpdateContentCommand.storeNewVersionEvenIfUnchanged( contentVersionKey ); } else { command = UpdateContentCommand.updateExistingVersion2( contentVersionKey ); } command.setContentName( params.name ); command.setSyncRelatedContent( true ); command.setSyncAccessRights( false ); command.setModifier( securityService.getImpersonatedPortalUser() ); command.setUpdateAsMainVersion( params.setAsCurrentVersion ); command.setContentKey( new ContentKey( params.contentKey ) ); command.setAvailableFrom( params.publishFrom ); command.setAvailableTo( params.publishTo ); command.setStatus( ContentStatus.get( params.status ) ); command.setUseCommandsBinaryDataToRemove( true ); command.setUseCommandsBinaryDataToAdd( true ); command.setChangeComment( params.changeComment ); if ( params.siteKey != null ) { command.setSiteKey( new SiteKey( params.siteKey ) ); } if ( params.contentData != null ) { final ContentTypeEntity contentType = resolveContentType( params.contentKey ); final ContentDataResolver customContentResolver = new ContentDataResolver(); final CustomContentData newContentData = customContentResolver.resolveContentdata( params.contentData, contentType ); command.setContentData( newContentData ); if ( !params.createNewVersion ) { // only delete previous binaries if we are overwriting current version final ContentVersionEntity persistedVersion = contentVersionDao.findByKey( contentVersionKey ); final CustomContentData persistedContentData = (CustomContentData) persistedVersion.getContentData(); final List<BinaryDataEntry> deletedBinaries = persistedContentData.getRemovedBinaryDataEntries( newContentData ); command.setBinaryDataToRemove( BinaryDataEntry.createBinaryDataKeyList( deletedBinaries ) ); command.setUseCommandsBinaryDataToRemove( true ); } // Find new binaries final List<BinaryDataEntry> binaryEntries = newContentData.getBinaryDataEntryList(); command.setBinaryDataToAdd( BinaryDataAndBinary.convert( binaryEntries ) ); command.setUseCommandsBinaryDataToAdd( true ); } else { // only update the meta data in this case.. } if ( params.updateStrategy == ContentDataInputUpdateStrategy.REPLACE_NEW ) { command.setUpdateStrategy( UpdateStrategy.MODIFY ); } final UpdateContentResult updateContentResult = contentService.updateContent( command ); if ( updateContentResult.isAnyChangesMade() ) { new PageCacheInvalidatorForContent( pageCacheService ).invalidateForContent( updateContentResult.getTargetedVersion() ); } return updateContentResult.getTargetedVersionKey().toInt(); } public void moveContent( MoveContentParams params ) { validateMoveContentParams( params ); ContentEntity content = contentDao.findByKey( new ContentKey( params.contentKey ) ); if ( content == null ) { throw new IllegalArgumentException( "No content for given contentKey: " + params.contentKey ); } CategoryEntity category = categoryDao.findByKey( new CategoryKey( params.categoryKey ) ); if ( category == null ) { throw new IllegalArgumentException( "No category for given categoryKey: " + params.categoryKey ); } contentService.moveContent( securityService.getImpersonatedPortalUser(), content, category ); } public int createFileContent( CreateFileContentParams params ) { validateCreateFileContentParams( params ); CategoryEntity category = categoryDao.findByKey( new CategoryKey( params.categoryKey ) ); UserEntity runningUser = securityService.getImpersonatedPortalUser(); LegacyFileContentData contentdata = (LegacyFileContentData) fileContentResolver.resolveContentdata( params.fileContentData ); List<BinaryDataAndBinary> binaryDataEntries = new ArrayList<BinaryDataAndBinary>(); binaryDataEntries.add( BinaryDataAndBinary.convertFromFileBinaryInput( params.fileContentData.binary ) ); CreateContentCommand createCommand = new CreateContentCommand(); createCommand.setAccessRightsStrategy( CreateContentCommand.AccessRightsStrategy.INHERIT_FROM_CATEGORY ); createCommand.setCreator( runningUser ); createCommand.setStatus( ContentStatus.get( params.status ) ); createCommand.setPriority( 0 ); createCommand.setCategory( category ); createCommand.setLanguage( category.getUnitExcludeDeleted().getLanguage() ); createCommand.setAvailableFrom( params.publishFrom ); createCommand.setAvailableTo( params.publishTo ); createCommand.setContentData( contentdata ); createCommand.setContentName( new PrettyPathNameCreator( transliterate ).generatePrettyPathName( contentdata.getTitle() ) ); createCommand.setBinaryDatas( binaryDataEntries ); createCommand.setUseCommandsBinaryDataToAdd( true ); if ( params.siteKey != null ) { createCommand.setSiteKey( new SiteKey( params.siteKey ) ); } ContentKey contentKey = contentService.createContent( createCommand ); return contentKey.toInt(); } public int updateFileContent( UpdateFileContentParams params ) { validateUpdateFileContentParams( params ); ContentVersionKey contentVersionKey = resolveContentVersionKey( params.createNewVersion, params.contentKey, params.contentVersionKey ); UpdateContentCommand command; if ( params.createNewVersion ) { command = UpdateContentCommand.storeNewVersionEvenIfUnchanged( contentVersionKey ); } else { command = UpdateContentCommand.updateExistingVersion2( contentVersionKey ); } command.setContentKey( new ContentKey( params.contentKey ) ); command.setSyncRelatedContent( false ); command.setSyncAccessRights( false ); command.setModifier( securityService.getImpersonatedPortalUser() ); command.setAvailableFrom( params.publishFrom ); command.setAvailableTo( params.publishTo ); command.setStatus( ContentStatus.get( params.status ) ); if ( params.siteKey != null ) { command.setSiteKey( new SiteKey( params.siteKey ) ); } LegacyFileContentData newContentData; List<BinaryDataAndBinary> binariesToAdd = null; List<BinaryDataKey> binariesToRemove = null; if ( params.fileContentData != null ) { newContentData = (LegacyFileContentData) fileContentResolver.resolveContentdata( params.fileContentData ); command.setContentData( newContentData ); if ( !params.createNewVersion ) { // only delete previous binaries if we are overwriting current version ContentVersionEntity persistedVersion = contentVersionDao.findByKey( contentVersionKey ); LegacyFileContentData previousContentData = (LegacyFileContentData) persistedVersion.getContentData(); binariesToRemove = previousContentData.getRemovedBinaries( newContentData ); } // Find new binaries binariesToAdd = newContentData.getBinaryDataAndBinaryList(); } else { // only update the meta data in this case.. } command.setUpdateAsMainVersion( params.setAsCurrentVersion ); command.setUseCommandsBinaryDataToAdd( true ); command.setBinaryDataToAdd( binariesToAdd ); command.setUseCommandsBinaryDataToRemove( true ); command.setBinaryDataToRemove( binariesToRemove ); if ( params.siteKey != null ) { command.setSiteKey( new SiteKey( params.siteKey ) ); } UpdateContentResult updateContentResult = contentService.updateContent( command ); if ( updateContentResult.isAnyChangesMade() ) { new PageCacheInvalidatorForContent( pageCacheService ).invalidateForContent( updateContentResult.getTargetedVersion() ); } return updateContentResult.getTargetedVersionKey().toInt(); } private void validateUpdateFileContentParams( UpdateFileContentParams params ) { if ( params.contentKey == null ) { throw new IllegalArgumentException( "contentKey must be specified" ); } if ( params.fileContentData == null ) { throw new IllegalArgumentException( "data must be specified" ); } if ( params.status == null ) { throw new IllegalArgumentException( "status must be specified" ); } if ( params.publishFrom != null && params.publishTo != null && !params.publishTo.after( params.publishFrom ) ) { throw new IllegalArgumentException( "publishTo must be after publishFrom" ); } ContentEntity content = contentDao.findByKey( new ContentKey( params.contentKey ) ); if ( content == null ) { throw new IllegalArgumentException( "No content for given contentKey: " + params.contentKey ); } } private CategoryEntity validateCreateContentParams( CreateContentParams params ) { if ( params.categoryKey == null ) { throw new IllegalArgumentException( "categoryKey must be specified" ); } if ( params.status == null ) { throw new IllegalArgumentException( "status must be specified" ); } if ( params.contentData == null ) { throw new IllegalArgumentException( "contentData must be specified" ); } if ( params.publishFrom != null && params.publishTo != null && !params.publishTo.after( params.publishFrom ) ) { throw new IllegalArgumentException( "publishTo must be after publishFrom" ); } CategoryEntity category = categoryDao.findByKey( new CategoryKey( params.categoryKey ) ); if ( category == null ) { throw new IllegalArgumentException( "category does not exists, id: " + params.categoryKey ); } return category; } private void validateCreateFileContentParams( CreateFileContentParams params ) { if ( params.categoryKey == null ) { throw new IllegalArgumentException( "categoryKey must be specified" ); } if ( params.fileContentData == null ) { throw new IllegalArgumentException( "data must be specified" ); } if ( params.status == null ) { throw new IllegalArgumentException( "status must be specified" ); } if ( params.publishFrom != null && params.publishTo != null && !params.publishTo.after( params.publishFrom ) ) { throw new IllegalArgumentException( "publishTo must be after publishFrom" ); } CategoryEntity category = categoryDao.findByKey( new CategoryKey( params.categoryKey ) ); if ( category == null ) { throw new IllegalArgumentException( "category does not exists, id: " + params.categoryKey ); } } private void validateCreateImageContentParams( CreateImageContentParams params ) { if ( params.categoryKey == null ) { throw new IllegalArgumentException( "categoryKey must be specified" ); } if ( params.status == null ) { throw new IllegalArgumentException( "status must be specified" ); } if ( params.contentData == null ) { throw new IllegalArgumentException( "data must be specified" ); } if ( params.publishFrom != null && params.publishTo != null && !params.publishTo.after( params.publishFrom ) ) { throw new IllegalArgumentException( "publishTo must be after publishFrom" ); } CategoryEntity category = categoryDao.findByKey( new CategoryKey( params.categoryKey ) ); if ( category == null ) { throw new IllegalArgumentException( "category does not exists, id: " + params.categoryKey ); } } private void validateUpdateContentParams( UpdateContentParams params ) { if ( params.contentKey == null ) { throw new IllegalArgumentException( "contentKey must be specified" ); } if ( params.updateStrategy == null ) { throw new IllegalArgumentException( "updateStrategy must be specified" ); } if ( params.publishFrom != null && params.publishTo != null && !params.publishTo.after( params.publishFrom ) ) { throw new IllegalArgumentException( "publishTo must be after publishFrom" ); } if ( params.createNewVersion && params.contentData == null && params.updateStrategy == ContentDataInputUpdateStrategy.REPLACE_ALL ) { throw new IllegalArgumentException( "contentData must be specified if you want to create new version when updateStrategy is " + ContentDataInputUpdateStrategy.REPLACE_ALL ); } if ( params.contentVersionKey != null && params.createNewVersion ) { throw new IllegalArgumentException( "There is no meaning in wanting to both update one specific version and create a new version" ); } ContentEntity persistedContent = contentDao.findByKey( new ContentKey( params.contentKey ) ); if ( persistedContent == null ) { throw new IllegalArgumentException( "No content for given contentKey: " + params.contentKey ); } int currentStatus = persistedContent.getMainVersion().getStatus().getKey(); if ( !params.createNewVersion && currentStatus != ContentStatus.DRAFT.getKey() && params.contentData != null ) { throw new IllegalArgumentException( "Only allowed to overwrite a draft content version - create new version instead" ); } if ( params.status != null ) { boolean currentStatusIsApprovedOrArchived = currentStatus == ContentStatus.APPROVED.getKey() || currentStatus == ContentStatus.ARCHIVED.getKey(); if ( currentStatusIsApprovedOrArchived ) { boolean statusChangingingToDraft = params.status == ContentStatus.DRAFT.getKey(); boolean statusChangingToSnapshot = params.status == ContentStatus.SNAPSHOT.getKey(); if ( !params.createNewVersion && ( statusChangingingToDraft || statusChangingToSnapshot ) ) { throw new IllegalArgumentException( "Not allowed to change status of an approved or archived content version - create new content version instead" ); } } } } private void validateMoveContentParams( MoveContentParams params ) { if ( params.contentKey == null ) { throw new IllegalArgumentException( "contentKey must be specified" ); } if ( params.categoryKey == null ) { throw new IllegalArgumentException( "categoryKey must be specified" ); } } private ContentVersionKey resolveContentVersionKey( boolean createNewVersion, int contentKey, Integer contentVeresionKey ) { ContentEntity persistedContent = contentDao.findByKey( new ContentKey( contentKey ) ); ContentVersionKey contentVersionKey; if ( createNewVersion ) { contentVersionKey = persistedContent.getMainVersion().getKey(); } else if ( contentVeresionKey == null ) { contentVersionKey = persistedContent.getMainVersion().getKey(); } else { contentVersionKey = new ContentVersionKey( contentVeresionKey ); } return contentVersionKey; } private ContentTypeEntity resolveContentType( int contentKey ) { ContentEntity persistedContent = contentDao.findByKey( new ContentKey( contentKey ) ); return persistedContent.getCategory().getContentType(); } private void checkContentIsOnline( final ContentEntity content ) { if ( previewService.isInPreview() ) { PreviewContext previewContext = previewService.getPreviewContext(); if ( previewContext.isPreviewingContent() && previewContext.getContentPreviewContext().treatContentAsAvailableEvenIfOffline( content.getKey() ) ) { // when in preview, the content doesn't need to be online return; } } if ( !content.isOnline( timeService.getNowAsDateTime() ) ) { throw AttachmentNotFoundException.notFound( content.getKey() ); } } private BinaryData createBinaryData( ContentBinaryDataEntity contentBinaryData ) { boolean anonAccess = contentBinaryData.getContentVersion().getContent().hasAccessRightSet( securityService.getAnonymousUser().getUserGroup(), ContentAccessType.READ ); BinaryData binaryData = new BinaryData(); binaryData.key = contentBinaryData.getBinaryData().getKey(); binaryData.contentKey = contentBinaryData.getContentVersion().getContent().getKey().toInt(); binaryData.setSafeFileName( contentBinaryData.getBinaryData().getName() ); binaryData.timestamp = contentBinaryData.getBinaryData().getCreatedAt(); binaryData.anonymousAccess = anonAccess; BlobRecord blob = this.binaryDataDao.getBlob( contentBinaryData.getBinaryData() ); binaryData.data = blob.getAsBytes(); return binaryData; } private void assertMinValue( String name, int value, int minValue ) { if ( value < minValue ) { throw new IllegalArgumentException( "Parameter [" + name + "] must be >= " + minValue ); } } private Document createBinaryDocument( BinaryData binaryData ) { if ( binaryData == null ) { return null; } Element binaryElem = new Element( "binary" ); Element fileNameElem = new Element( "filename" ); fileNameElem.setText( binaryData.fileName ); binaryElem.addContent( fileNameElem ); Element binaryKeyElem = new Element( "binarykey" ); binaryKeyElem.setText( String.valueOf( binaryData.key ) ); binaryElem.addContent( binaryKeyElem ); Element contentKeyElem = new Element( "contentkey" ); contentKeyElem.setText( String.valueOf( binaryData.contentKey ) ); binaryElem.addContent( contentKeyElem ); Element sizeElem = new Element( "size" ); sizeElem.setText( String.valueOf( binaryData.data.length ) ); binaryElem.addContent( sizeElem ); Element timestampElem = new Element( "timestamp" ); timestampElem.setText( binaryData.timestamp.toString() ); binaryElem.addContent( timestampElem ); Element dataElem = new Element( "data" ); dataElem.setText( Base64Util.encode( binaryData.data ) ); binaryElem.addContent( dataElem ); return new Document( binaryElem ); } }