Skip to content

Commit

Permalink
#13395 CopyContentlet done (#13415)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdotcms authored and jgambarios committed Jan 18, 2018
1 parent 1f43a57 commit f05ba00
Show file tree
Hide file tree
Showing 13 changed files with 421 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package com.dotmarketing.portlets.workflows.business;

import com.dotcms.contenttype.business.ContentTypeAPI;
import com.dotcms.contenttype.model.field.DataTypes;
import com.dotcms.contenttype.model.field.Field;
import com.dotcms.contenttype.model.field.FieldBuilder;
import com.dotcms.contenttype.model.field.TextField;
import com.dotcms.contenttype.model.type.BaseContentType;
import com.dotcms.contenttype.model.type.ContentType;
import com.dotcms.contenttype.model.type.ContentTypeBuilder;
import com.dotcms.contenttype.transform.contenttype.StructureTransformer;
import com.dotcms.system.event.local.model.EventSubscriber;
import com.dotcms.util.IntegrationTestInitService;
import com.dotmarketing.beans.Host;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.exception.AlreadyExistException;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotSecurityException;
import com.dotmarketing.portlets.contentlet.business.ContentletAPI;
import com.dotmarketing.portlets.contentlet.model.Contentlet;
import com.dotmarketing.portlets.folders.business.FolderAPI;
import com.dotmarketing.portlets.workflows.actionlet.CopyActionlet;
import com.dotmarketing.portlets.workflows.actionlet.SaveContentActionlet;
import com.dotmarketing.portlets.workflows.actionlet.event.CopyActionletEvent;
import com.dotmarketing.portlets.workflows.model.WorkflowProcessor;
import com.dotmarketing.util.UUIDGenerator;
import com.liferay.portal.model.User;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class CopyActionletTest extends BaseWorkflowIntegrationTest {

private static CreateSchemeStepActionResult schemeStepActionResult = null;
private static WorkflowAPI workflowAPI = null;
private static ContentletAPI contentletAPI = null;
private static ContentType type = null;
private static Contentlet contentlet = null;
private static Contentlet contentletCopy = null;


@BeforeClass
public static void prepare() throws Exception {
//Setting web app environment

IntegrationTestInitService.getInstance().init();
CopyActionletTest.workflowAPI = APILocator.getWorkflowAPI();
final ContentTypeAPI contentTypeAPI = APILocator.getContentTypeAPI(APILocator.systemUser());
CopyActionletTest.contentletAPI = APILocator.getContentletAPI();

// creates the scheme and actions
CopyActionletTest.schemeStepActionResult = CopyActionletTest.createSchemeStepActionActionlet
("CopyActionlet" + UUIDGenerator.generateUuid(), "step1", "action1", CopyActionlet.class);

// creates the type to trigger the scheme
CopyActionletTest.createTestType(contentTypeAPI);

// associated the scheme to the type
CopyActionletTest.workflowAPI.saveSchemesForStruct(new StructureTransformer(CopyActionletTest.type).asStructure(),
Arrays.asList(CopyActionletTest.schemeStepActionResult.getScheme()));

}

private static void createTestType(final ContentTypeAPI contentTypeAPI) throws DotDataException, DotSecurityException {

CopyActionletTest.type = contentTypeAPI.save(
ContentTypeBuilder.builder(BaseContentType.CONTENT.immutableClass())
.expireDateVar(null).folder(FolderAPI.SYSTEM_FOLDER).host(Host.SYSTEM_HOST)
.description("DotCopyActionletTest...")
.name("DotCopyActionletTest").owner(APILocator.systemUser().toString())
.variable("DotCopyActionletTest").build());

final List<Field> fields = new ArrayList<>(CopyActionletTest.type.fields());

fields.add(FieldBuilder.builder(TextField.class).name("title").variable("title")
.contentTypeId(CopyActionletTest.type.id()).dataType(DataTypes.TEXT).indexed(true).build());
fields.add(FieldBuilder.builder(TextField.class).name("txt").variable("txt")
.contentTypeId(CopyActionletTest.type.id()).dataType(DataTypes.TEXT).indexed(true).build());

CopyActionletTest.type = contentTypeAPI.save(CopyActionletTest.type, fields);
}

/**
* Remove the content type and workflows created
*/
@AfterClass
public static void cleanup() throws DotDataException, DotSecurityException, AlreadyExistException {

try {

if (null != CopyActionletTest.contentlet) {

CopyActionletTest.contentletAPI.delete(CopyActionletTest.contentlet, APILocator.systemUser(), false);
}

if (null != CopyActionletTest.contentletCopy) {

CopyActionletTest.contentletAPI.delete(CopyActionletTest.contentletCopy, APILocator.systemUser(), false);
}
} finally {

try {

if (null != CopyActionletTest.schemeStepActionResult) {

CopyActionletTest.cleanScheme(CopyActionletTest.schemeStepActionResult.getScheme());
}
} finally {

if (null != CopyActionletTest.type) {

ContentTypeAPI contentTypeAPI = APILocator.getContentTypeAPI(APILocator.systemUser());
contentTypeAPI.delete(CopyActionletTest.type);
}
}
}
} // cleanup

@Test
public void saveContentTest() throws DotDataException, DotSecurityException {

final long languageId = APILocator.getLanguageAPI().getDefaultLanguage().getId();
final Contentlet contentlet = new Contentlet();
final User user = APILocator.systemUser();
contentlet.setContentTypeId(CopyActionletTest.type.id());
contentlet.setOwner(APILocator.systemUser().toString());
contentlet.setModDate(new Date());
contentlet.setLanguageId(languageId);
contentlet.setStringProperty("title", "Test Save");
contentlet.setStringProperty("txt", "Test Save Text");
contentlet.setHost(Host.SYSTEM_HOST);
contentlet.setFolder(FolderAPI.SYSTEM_FOLDER);

APILocator.getLocalSystemEventsAPI().subscribe(CopyActionletEvent.class, new EventSubscriber<CopyActionletEvent>() {
@Override
public void notify(CopyActionletEvent event) {

contentletCopy = event.getCopyContentlet();
}
});

// first save
final Contentlet contentlet1 = CopyActionletTest.contentletAPI.checkin(contentlet, user, false);
final String firstIdentifier = contentlet1.getIdentifier();
final String firstInode = contentlet1.getInode();

CopyActionletTest.contentlet = contentlet1;

// triggering the copy action
contentlet1.setStringProperty(Contentlet.WORKFLOW_ACTION_KEY,
this.schemeStepActionResult.getAction().getId());
contentlet1.setBoolProperty(CopyActionlet.NOTIFY_SYNC_COPY_EVENT,
true);

final WorkflowProcessor processor =
CopyActionletTest.workflowAPI.fireWorkflowPreCheckin(contentlet1, user);

CopyActionletTest.workflowAPI.fireWorkflowPostCheckin(processor);

Assert.assertNotNull(contentletCopy);
Assert.assertNotNull(contentletCopy.getIdentifier());
Assert.assertNotNull(contentletCopy.getInode());
contentletAPI.isInodeIndexed(contentletCopy.getInode());

final Contentlet contentlet2 = CopyActionletTest.contentletAPI.findContentletByIdentifier
(CopyActionletTest.contentletCopy.getIdentifier(),
false, languageId, user, false);

// the contentlet save by the action must be not null, should has a new version.
Assert.assertNotNull(contentlet2);
Assert.assertNotNull(contentlet2.getIdentifier());
Assert.assertNotNull(contentlet2.getInode());
Assert.assertFalse (contentlet2.getIdentifier().equals(firstIdentifier));
Assert.assertFalse (contentlet2.getInode().equals(firstInode));
Assert.assertEquals ("Test Save", contentlet2.getStringProperty("title"));
Assert.assertEquals ("Test Save Text", contentlet2.getStringProperty("txt"));

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5014,7 +5014,8 @@ public List<Map<String, Serializable>> DBSearch(Query query, User user,boolean r
* @throws DotContentletStateException
* The contentlet object could not be saved.
*/
private Contentlet copyContentlet(Contentlet contentletToCopy, Host host, Folder folder, User user, final String copySuffix, boolean respectFrontendRoles) throws DotDataException, DotSecurityException, DotContentletStateException {
@Override
public Contentlet copyContentlet(Contentlet contentletToCopy, Host host, Folder folder, User user, final String copySuffix, boolean respectFrontendRoles) throws DotDataException, DotSecurityException, DotContentletStateException {
Contentlet resultContentlet = new Contentlet();
String newIdentifier = Strings.EMPTY;
ArrayList<Contentlet> versionsToCopy = new ArrayList<Contentlet>();
Expand Down
1 change: 1 addition & 0 deletions dotCMS/src/main/java/com/dotcms/util/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* @version 3.7
* @since Jun 8, 2016
*/
@FunctionalInterface
public interface Converter<Original, Destiny> extends Serializable {

/**
Expand Down
1 change: 1 addition & 0 deletions dotCMS/src/main/java/com/dotcms/util/Delegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* @since Jul 13, 2016
*
*/
@FunctionalInterface
public interface Delegate<T> {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Returnable delegate without any parameter.
* @author jsanca
*/
@FunctionalInterface
public interface ReturnableDelegate<T> {

/**
Expand Down
1 change: 1 addition & 0 deletions dotCMS/src/main/java/com/dotcms/util/VoidDelegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* @since Jul 13, 2016
*
*/
@FunctionalInterface
public interface VoidDelegate {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,25 @@ public Contentlet copyContentlet(Contentlet contentlet, Host host, User user, bo
* @throws DotContentletStateException
*/
public Contentlet copyContentlet(Contentlet contentlet, Folder folder, User user, boolean appendCopyToFileName, boolean respectFrontendRoles) throws DotDataException, DotSecurityException, DotContentletStateException;


/**
* Copies a contentlet, including all its fields including binary files, image and file fields are pointers and the are preserved as the are
* so if source contentlet points to image A and resulting new contentlet will point to same image A as well, also copies source permissions.
* And moves the the new piece of content to the given folder. CopySuffix will be to append suffix to the file name.
*
* @param contentletToCopy
* @param host
* @param folder
* @param user
* @param copySuffix
* @param respectFrontendRoles
* @return Contentlet
* @throws DotDataException
* @throws DotSecurityException
* @throws DotContentletStateException
*/
Contentlet copyContentlet(Contentlet contentletToCopy, Host host, Folder folder, User user, final String copySuffix, boolean respectFrontendRoles) throws DotDataException, DotSecurityException, DotContentletStateException;

/**
* The search here takes a lucene query and pulls Contentlets for you. You can pass sortBy as null if you do not
* have a field to sort by. limit should be 0 if no limit and the offset should be -1 is you are not paginating.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,30 @@ public Contentlet copyContentlet(Contentlet contentlet, Folder folder, User user
return c;
}

@Override
public Contentlet copyContentlet(final Contentlet contentletToCopy,
final Host host, final Folder folder, final User user, final String copySuffix,
final boolean respectFrontendRoles) throws DotDataException, DotSecurityException, DotContentletStateException {

for (ContentletAPIPreHook pre : preHooks) {

final boolean preResult = pre.copyContentlet(contentletToCopy, host, folder, user, copySuffix, respectFrontendRoles);
if(!preResult) {
Logger.error(this, "The following prehook failed " + pre.getClass().getName());
throw new DotRuntimeException("The following prehook failed " + pre.getClass().getName());
}
}

final Contentlet copiedContentlet =
this.conAPI.copyContentlet(contentletToCopy, host, folder, user, copySuffix, respectFrontendRoles);

for(ContentletAPIPostHook post : postHooks) {
post.copyContentlet(contentletToCopy, host, folder, user, copySuffix, respectFrontendRoles, copiedContentlet);
}

return copiedContentlet;
}

@Override
public boolean isInodeIndexed(String inode) {
for(ContentletAPIPreHook pre : preHooks){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,20 @@ public default void copyContentlet(Contentlet currentContentlet, Folder folder,
* @param returnValue - value returned by primary API Method
*/
public default void copyContentlet(Contentlet currentContentlet, Folder folder, User user, boolean appendCopyToFileName, boolean respectFrontendRoles,Contentlet returnValue){}


/**
* Makes a copy of a content.
* @param contentletToCopy
* @param host
* @param folder
* @param user
* @param copySuffix
* @param respectFrontendRoles
* @param returnValue - value returned by primary API Method
*/
public default void copyContentlet(final Contentlet contentletToCopy,
final Host host, final Folder folder, final User user, final String copySuffix,
final boolean respectFrontendRoles, Contentlet returnValue) {}
/**
* The search here takes a lucene query and pulls Contentlets for you. You can pass sortBy as null if you do not
* have a field to sort by. limit should be 0 if no limit and the offset should be -1 is you are not paginating.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,24 @@ public default boolean copyContentlet(Contentlet currentContentlet, Folder folde
public default boolean copyContentlet(Contentlet currentContentlet, Folder folder, User user, boolean appendCopyToFileName, boolean respectFrontendRoles){
return true;
}


/**
* Make a copye of a contentlet which the copySuffix to rename the filename + suffix.
* @param contentletToCopy
* @param host
* @param folder
* @param user
* @param copySuffix
* @param respectFrontendRoles
* @return
*/
public default boolean copyContentlet(final Contentlet contentletToCopy,
final Host host, final Folder folder, final User user, final String copySuffix,
final boolean respectFrontendRoles) {
return true;
}


/**
* The search here takes a lucene query and pulls Contentlets for you. You can pass sortBy as null if you do not
* have a field to sort by. limit should be 0 if no limit and the offset should be -1 is you are not paginating.
Expand Down
Loading

0 comments on commit f05ba00

Please sign in to comment.