org.betaconceptframework.astroboa.test.engine.AbstractRepositoryTest.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.test.engine.AbstractRepositoryTest.java

Source

 /*
  * Copyright (C) 2005-2012 BetaCONCEPT Limited
  *
  * This file is part of Astroboa.
  *
  * Astroboa is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * Astroboa is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Astroboa.  If not, see <http://www.gnu.org/licenses/>.
  */
 package org.betaconceptframework.astroboa.test.engine;

 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;

 import javax.activation.MimetypesFileTypeMap;
 import javax.jcr.Session;
 import javax.xml.datatype.DatatypeConfigurationException;
 import javax.xml.datatype.DatatypeConstants;
 import javax.xml.datatype.DatatypeFactory;

 import org.apache.commons.compress.archivers.ArchiveStreamFactory;
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DurationFormatUtils;
 import org.apache.log4j.Level;
 import org.betaconceptframework.astroboa.api.model.BinaryChannel;
 import org.betaconceptframework.astroboa.api.model.BinaryProperty;
 import org.betaconceptframework.astroboa.api.model.BooleanProperty;
 import org.betaconceptframework.astroboa.api.model.CalendarProperty;
 import org.betaconceptframework.astroboa.api.model.CmsProperty;
 import org.betaconceptframework.astroboa.api.model.CmsRepositoryEntity;
 import org.betaconceptframework.astroboa.api.model.ContentObject;
 import org.betaconceptframework.astroboa.api.model.DoubleProperty;
 import org.betaconceptframework.astroboa.api.model.LongProperty;
 import org.betaconceptframework.astroboa.api.model.ObjectReferenceProperty;
 import org.betaconceptframework.astroboa.api.model.RepositoryUser;
 import org.betaconceptframework.astroboa.api.model.SimpleCmsProperty;
 import org.betaconceptframework.astroboa.api.model.Space;
 import org.betaconceptframework.astroboa.api.model.StringProperty;
 import org.betaconceptframework.astroboa.api.model.Taxonomy;
 import org.betaconceptframework.astroboa.api.model.Topic;
 import org.betaconceptframework.astroboa.api.model.TopicReferenceProperty;
 import org.betaconceptframework.astroboa.api.model.definition.Localization;
 import org.betaconceptframework.astroboa.api.model.exception.CmsException;
 import org.betaconceptframework.astroboa.api.model.io.FetchLevel;
 import org.betaconceptframework.astroboa.api.model.io.ImportConfiguration;
 import org.betaconceptframework.astroboa.api.model.io.ImportConfiguration.PersistMode;
 import org.betaconceptframework.astroboa.api.model.io.ImportReport;
 import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType;
 import org.betaconceptframework.astroboa.api.model.io.SerializationConfiguration;
 import org.betaconceptframework.astroboa.api.model.io.SerializationReport;
 import org.betaconceptframework.astroboa.api.model.query.CacheRegion;
 import org.betaconceptframework.astroboa.api.model.query.CmsOutcome;
 import org.betaconceptframework.astroboa.api.model.query.Order;
 import org.betaconceptframework.astroboa.api.model.query.criteria.CmsCriteria;
 import org.betaconceptframework.astroboa.api.model.query.criteria.ContentObjectCriteria;
 import org.betaconceptframework.astroboa.api.model.query.criteria.RepositoryUserCriteria;
 import org.betaconceptframework.astroboa.api.model.query.criteria.SpaceCriteria;
 import org.betaconceptframework.astroboa.api.model.query.criteria.TopicCriteria;
 import org.betaconceptframework.astroboa.api.security.IdentityPrincipal;
 import org.betaconceptframework.astroboa.api.security.exception.CmsUnauthorizedAccessException;
 import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder;
 import org.betaconceptframework.astroboa.engine.definition.ContentDefinitionConfiguration;
 import org.betaconceptframework.astroboa.engine.definition.RepositoryEntityResolver;
 import org.betaconceptframework.astroboa.engine.jcr.dao.ImportDao;
 import org.betaconceptframework.astroboa.engine.jcr.dao.SerializationDao;
 import org.betaconceptframework.astroboa.engine.jcr.identitystore.jackrabbit.JackrabbitIdentityStoreDao;
 import org.betaconceptframework.astroboa.engine.jcr.io.ContentSourceExtractor;
 import org.betaconceptframework.astroboa.engine.jcr.io.SerializationBean.CmsEntityType;
 import org.betaconceptframework.astroboa.engine.jcr.util.JcrNodeUtils;
 import org.betaconceptframework.astroboa.model.factory.CmsCriteriaFactory;
 import org.betaconceptframework.astroboa.model.factory.CmsRepositoryEntityFactory;
 import org.betaconceptframework.astroboa.model.factory.CmsRepositoryEntityFactoryForActiveClient;
 import org.betaconceptframework.astroboa.model.jaxb.CmsEntitySerialization;
 import org.betaconceptframework.astroboa.test.AbstractAstroboaTest;
 import org.betaconceptframework.astroboa.test.AstroboaTestContext;
 import org.betaconceptframework.astroboa.test.TestConstants;
 import org.betaconceptframework.astroboa.test.log.TestLogPolicy;
 import org.betaconceptframework.astroboa.test.util.JAXBTestUtils;
 import org.betaconceptframework.astroboa.test.util.JAXBValidationUtils;
 import org.betaconceptframework.astroboa.test.util.TestUtils;
 import org.betaconceptframework.astroboa.util.CmsConstants;
 import org.betaconceptframework.astroboa.util.DateUtils;
 import org.slf4j.LoggerFactory;
 import org.springframework.core.io.ClassPathResource;
 import org.testng.Assert;
 import org.testng.annotations.AfterTest;

 /**
  * @author Gregory Chomatas (gchomatas@betaconcept.com)
  * @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
  * 
  */
 public abstract class AbstractRepositoryTest extends AbstractAstroboaTest {

     protected CmsRepositoryEntityFactory cmsRepositoryEntityFactory;
     protected TestCmsDao testCmsDao;
     private Session session;

     protected File logo;
     protected File logo2;

     protected Random random = new Random(10000);

     protected final String TEST_CONTENT_TYPE = "test";
     protected final String EXTENDED_TEST_CONTENT_TYPE = "extendedTest";
     protected final String DIRECT_EXTENDED_TEST_CONTENT_TYPE = "extendedTestDirectlyUsingType";

     protected final String INDENPENDENT_CONTENT_TYPE_NAME = "independentObject";
     protected final String DIRECT_EXTENDED_INDEPENDENT_CONTENT_TYPE_NAME = "directlyExtendingIndependentBaseTypeIndependentObject";
     protected final String EXTENDED_INDEPENDENT_CONTENT_TYPE_NAME = "extendingIndependentBaseTypeIndependentObject";

     protected JAXBValidationUtils jaxbValidationUtils;
     protected SerializationDao serializationDao;
     protected ImportDao importDao;
     protected RepositoryEntityResolver repositoryEntityResolver;
     protected ContentSourceExtractor contentSourceExtractor;
     protected RepositoryContentValidator repositoryContentValidator;

     protected boolean prettyPrint = false;

     private DatatypeFactory df;

     //The value of this property is provided in pom.xml
     //by maven-surefire-plugin configuration properties
     private String astroboaVersion = null;

     protected void preSetup() throws Exception {

         astroboaVersion = System.getProperty("astroboaVersion");

         TestLogPolicy.setLevelForLogger(Level.ERROR, ContentDefinitionConfiguration.class.getName());
         TestLogPolicy.setLevelForLogger(Level.ERROR, CmsEntitySerialization.class.getName());
         TestLogPolicy.setLevelForLogger(Level.ERROR, JackrabbitIdentityStoreDao.class.getName());

         //If debug is enabled for this test then pretty print is enabled as well.
         prettyPrint = LoggerFactory.getLogger("org.betaconceptframework.astroboa.engine.AbstractRepositoryTest")
                 .isDebugEnabled();

         if (df == null) {
             try {
                 df = DatatypeFactory.newInstance();
             } catch (DatatypeConfigurationException e) {
                 throw new CmsException(e);
             }
         }
     }

     protected void postSetup() throws Exception {
         cmsRepositoryEntityFactory = CmsRepositoryEntityFactoryForActiveClient.INSTANCE.getFactory();
         testCmsDao = new TestCmsDao();
         contentSourceExtractor = new ContentSourceExtractor();
         repositoryContentValidator = new RepositoryContentValidator();

         serializationDao = AstroboaTestContext.INSTANCE.getBean(SerializationDao.class, "serializationDao");
         importDao = AstroboaTestContext.INSTANCE.getBean(ImportDao.class, "importDao");

         repositoryEntityResolver = AstroboaTestContext.INSTANCE.getBean(RepositoryEntityResolver.class,
                 "repositoryEntityResolver");

         copyFilesToUnmanagedDataStore();

         createUser(TestConstants.TEST_USER_NAME);

         TestLogPolicy.setDefaultLevelForLogger(ContentDefinitionConfiguration.class.getName());
         TestLogPolicy.setDefaultLevelForLogger(CmsEntitySerialization.class.getName());
         TestLogPolicy.setDefaultLevelForLogger(JackrabbitIdentityStoreDao.class.getName());

         jaxbValidationUtils = new JAXBValidationUtils(repositoryEntityResolver, astroboaVersion);

     }

     protected String createUser(String username) throws IOException {

         loginToRepositoryRepresentingIdentityStoreAsSystem();

         String personUUID = null;
         if (userHasNotBeenCreated(username)) {
             String testUserXml = FileUtils.readFileToString(new ClassPathResource("person_test.xml").getFile());

             testUserXml = StringUtils.replace(testUserXml, "SYSTEM_USER_ID",
                     repositoryUserService.getSystemRepositoryUser().getId());

             testUserXml = StringUtils.replace(testUserXml, "USERNAME", username);

             ImportConfiguration configuration = ImportConfiguration.object()
                     .persist(PersistMode.PERSIST_ENTITY_TREE).version(false).updateLastModificationTime(true)
                     .build();

             ContentObject testUser = importDao.importContentObject(testUserXml, configuration);
             logger.debug("Created " + testUser.getContentObjectType() + " with id " + testUser.getId()
                     + " and system name " + testUser.getSystemName() + " representing user " + username + " in "
                     + " repository " + AstroboaClientContextHolder.getActiveRepositoryId());

             personUUID = testUser.getId();
         }

         loginToTestRepositoryAsSystem();

         if (repositoryUserService.getRepositoryUser(username) == null) {
             RepositoryUser repUser = CmsRepositoryEntityFactoryForActiveClient.INSTANCE.getFactory()
                     .newRepositoryUser();
             repUser.setExternalId(username);
             repUser.setLabel(username);

             repositoryUserService.save(repUser);
         }

         return personUUID;
     }

     protected void deleteUser(String username) {

         String systemName = "IDENTITY_STORE_" + username;
         ContentObject person = contentService.getContentObject(systemName,
                 ResourceRepresentationType.CONTENT_OBJECT_INSTANCE, FetchLevel.ENTITY, CacheRegion.NONE, null,
                 false);

         Assert.assertNotNull(person, "Person Object with system name " + systemName + " was not found");

         contentService.deleteContentObject(person.getId());

     }

     private boolean userHasNotBeenCreated(String username) {

         return !identityStore.userExists(username);

     }

     private void copyFilesToUnmanagedDataStore() throws IOException {

         logo = new ClassPathResource("logo.png").getFile();
         logo2 = new ClassPathResource("logo2.png").getFile();

         File unmanagedDataStore = new ClassPathResource("/repository/UnmanagedDataStore").getFile();

         FileUtils.copyFileToDirectory(logo, unmanagedDataStore);
         FileUtils.copyFileToDirectory(logo2, unmanagedDataStore);
     }

     protected BinaryChannel loadManagedBinaryChannel(File resource, String binaryChannelName) throws IOException {
         BinaryChannel image = cmsRepositoryEntityFactory.newBinaryChannel();
         image.setName(binaryChannelName);
         //image.setSize(resource.length());
         image.setContent(FileUtils.readFileToByteArray(resource));

         image.setSourceFilename(resource.getName());

         image.setMimeType(new MimetypesFileTypeMap().getContentType(resource));

         Calendar lastModifiedDate = Calendar.getInstance();
         lastModifiedDate.setTimeInMillis(resource.lastModified());

         image.setModified(lastModifiedDate);

         return image;
     }

     protected BinaryChannel loadUnManagedBinaryChannel(String resourceRelativePath, String binaryChannelName)
             throws IOException {
         BinaryChannel image = cmsRepositoryEntityFactory.newUnmanagedBinaryChannel(resourceRelativePath);

         image.setName(binaryChannelName);

         return image;
     }

     protected Session getSession() {
         if (session == null) {
             session = testCmsDao.getSession();
         }

         return session;
     }

     @AfterTest
     public void disableSecurity() {

         loginToTestRepositoryAsSystem();

         if (session != null) {
             session.logout();
             session = null;
         }
     }

     /* (non-Javadoc)
      * @see org.betaconceptframework.astroboa.test.AbstractAstroboaTest#login()
      */

     protected void loginToRepositoryRepresentingIdentityStoreAsSystem() {

         loginToRepository(TestConstants.TEST_IDENTITY_STORE_REPOSITORY_ID, IdentityPrincipal.SYSTEM, "betaconcept",
                 false);

     }

     protected ContentObject createContentObject(RepositoryUser systemUser, String systemName) {
         return createContentObjectForType(TEST_CONTENT_TYPE, systemUser, systemName);
     }

     protected ContentObject createContentObjectForType(String contentType, RepositoryUser systemUser,
             String systemName) {

         ContentObject contentObject = cmsRepositoryEntityFactory.newObjectForType(contentType);
         contentObject.setOwner(systemUser);
         contentObject.setSystemName(TestUtils.createValidSystemName(systemName));

         contentObject.getCmsProperty("accessibility.canBeReadBy");
         contentObject.getCmsProperty("accessibility.canBeUpdatedBy");
         contentObject.getCmsProperty("accessibility.canBeDeletedBy");
         ((StringProperty) contentObject.getCmsProperty("accessibility.canBeTaggedBy")).addSimpleTypeValue("NONE");

         String title = systemName;

         ((StringProperty) contentObject.getCmsProperty("profile.title")).setSimpleTypeValue(title);
         ((StringProperty) contentObject.getCmsProperty("profile.language")).addSimpleTypeValue("en");
         ((CalendarProperty) contentObject.getCmsProperty("profile.modified"))
                 .setSimpleTypeValue(Calendar.getInstance());

         return contentObject;
     }

     protected void removeRoleFromActiveSubject(String role) {

         if (AstroboaClientContextHolder.getActiveSecurityContext().hasRole(role)) {
             boolean roleRemoved = AstroboaClientContextHolder.getActiveSecurityContext().removeRole(role);

             if (!roleRemoved) {
                 logger.warn("Role {} was not removed from subject {}", role,
                         AstroboaClientContextHolder.getActiveSecurityContext().getSubject());
             }
         }
     }

     protected void addRoleToActiveSubject(String role) {

         boolean roleAdded = AstroboaClientContextHolder.getActiveSecurityContext().addRole(role);

         if (!roleAdded) {
             logger.warn("Role {} was not added to subject {}", role,
                     AstroboaClientContextHolder.getActiveSecurityContext().getSubject());
         }
     }

     protected void assertCmsUnauthorizedAccessExceptionIsThrownWithCorrectMessage(CmsException e,
             String expectedMessage, boolean startsWith, String methodName) {

         Throwable t = e;

         while (t != null && !(t instanceof CmsUnauthorizedAccessException)) {
             t = t.getCause();
         }

         if (t == null || !(t instanceof CmsUnauthorizedAccessException)) {
             throw new CmsException(
                     "Invalid exception thrown in method " + methodName + " Expected CmsUnauthorizedAccessException",
                     e);
         }

         //CmsUnauthorizedAccessException is thrown. Check message is correct

         if (startsWith) {
             Assert.assertTrue(t.getMessage() != null && t.getMessage().startsWith(expectedMessage),
                     "Invalid exception thrown in method " + methodName + " " + t.getMessage());
         } else {
             Assert.assertEquals(expectedMessage, t.getMessage(),
                     "Invalid exception thrown in method " + methodName + " " + e.getMessage());
         }

     }

     //Simply generate JSON to check if an exception is thrown
     protected void validateJson(CmsRepositoryEntity cmsRepositoryEntity) {
         //Just generate JSON to see if process throws an exception
         logger.debug("Created JSON :\n" + cmsRepositoryEntity.json(prettyPrint));

     }

     protected void validateJsonCmsOutcome(ContentObjectCriteria contentObjectCriteria) {
         //Just generate JSON to see if process throws an exception
         logger.debug("Created JSON :\n"
                 + contentService.searchContentObjects(contentObjectCriteria, ResourceRepresentationType.JSON));

     }

     protected List<String> getTestContentTypes() {
         return Arrays.asList(TEST_CONTENT_TYPE, EXTENDED_TEST_CONTENT_TYPE);
     }

     protected List<String> getIndependentContentTypes() {
         return Arrays.asList(INDENPENDENT_CONTENT_TYPE_NAME, EXTENDED_INDEPENDENT_CONTENT_TYPE_NAME,
                 DIRECT_EXTENDED_INDEPENDENT_CONTENT_TYPE_NAME);
     }

     protected Future<SerializationReport> serializeAllEntitiesOfType(final CmsEntityType entityTypeToBeSerialized,
             final SerializationConfiguration serializationConfiguration) {

         return serializationDao.serializeAllInstancesOfEntity(entityTypeToBeSerialized, serializationConfiguration);
     }

     @Override
     protected void preCleanup() {

     }

     @Override
     protected void postCleanup() {

     }

     protected void serializeUsingJCR(CmsEntityType cmsEntity) {

         long start = System.currentTimeMillis();

         String repositoryHomeDir = AstroboaClientContextHolder.getActiveClientContext().getRepositoryContext()
                 .getCmsRepository().getRepositoryHomeDirectory();

         File serializationHomeDir = new File(
                 repositoryHomeDir + File.separator + CmsConstants.SERIALIZATION_DIR_NAME);

         File zipFile = new File(serializationHomeDir,
                 "document" + DateUtils.format(Calendar.getInstance(), "ddMMyyyyHHmmss.sss") + ".zip");

         OutputStream out = null;
         ZipArchiveOutputStream os = null;

         try {

             if (!zipFile.exists()) {
                 FileUtils.touch(zipFile);
             }

             out = new FileOutputStream(zipFile);
             os = (ZipArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("zip", out);

             os.setFallbackToUTF8(true);

             //Serialize all repository using JCR
             os.putArchiveEntry(new ZipArchiveEntry("document-view.xml"));

             final Session session = getSession();

             switch (cmsEntity) {
             case OBJECT:
                 session.exportDocumentView(JcrNodeUtils.getContentObjectRootNode(session).getPath(), os, false,
                         false);
                 break;
             case REPOSITORY_USER:
                 session.exportDocumentView(JcrNodeUtils.getRepositoryUserRootNode(session).getPath(), os, false,
                         false);
                 break;
             case TAXONOMY:
                 session.exportDocumentView(JcrNodeUtils.getTaxonomyRootNode(session).getPath(), os, false, false);
                 break;
             case ORGANIZATION_SPACE:
                 session.exportDocumentView(JcrNodeUtils.getOrganizationSpaceNode(session).getPath(), os, false,
                         false);
                 break;
             case REPOSITORY:
                 session.exportDocumentView(JcrNodeUtils.getCMSSystemNode(session).getPath(), os, false, false);
                 break;

             default:
                 break;
             }

             os.closeArchiveEntry();

             os.finish();
             os.close();

         } catch (Exception e) {
             throw new CmsException(e);
         } finally {
             if (out != null) {
                 IOUtils.closeQuietly(out);
             }

             if (os != null) {
                 IOUtils.closeQuietly(os);
             }
             long serialzationDuration = System.currentTimeMillis() - start;

             logger.debug("Export entities using JCR finished in {} ",
                     DurationFormatUtils.formatDurationHMS(serialzationDuration));
         }
     }

protected void assertIOOfEntity(CmsEntityType cmsEntityTypeToBeSerialized, ImportConfiguration configuration, SerializationConfiguration serializationConfiguration) throws Throwable{
      
   loginToTestRepositoryAsSystem();
      
   SerializationReport serializationReport = exportEntity(cmsEntityTypeToBeSerialized, serializationConfiguration);
      
   URI serializationURI = retrieveUROfExportOutcome(serializationReport);
      
   validateExportXml(serializationURI);
      
   ImportReport importReport = importExportedEntityToCloneRepository(serializationURI, configuration);

   validateImport(importReport, serializationURI, cmsEntityTypeToBeSerialized);
      
   loginToTestRepositoryAsSystem();
      
}

protected void assertIOOfObjectsUsingCriteria(ContentObjectCriteria contentObjectCriteria, ImportConfiguration configuration, SerializationConfiguration serializationConfiguration) throws Throwable{
      
   loginToTestRepositoryAsSystem();
      
   SerializationReport serializationReport = exportObjects(contentObjectCriteria, serializationConfiguration);
      
   URI serializationURI = retrieveUROfExportOutcome(serializationReport);
      
   validateExportXml(serializationURI);
      
   ImportReport importReport = importExportedEntityToCloneRepository(serializationURI, configuration);

   validateImport(importReport, serializationURI, CmsEntityType.OBJECT);
   validateImport(importReport, serializationURI, CmsEntityType.TAXONOMY);
   validateImport(importReport, serializationURI, CmsEntityType.TOPIC);
      
   loginToTestRepositoryAsSystem();
      
}

     protected void validateImport(ImportReport importReport, URI exportURI, CmsEntityType cmsEntityToExport)
             throws Throwable {

         try {
             Assert.assertTrue(importReport.getErrors().isEmpty(), "Import failed \n " + importReport.getErrors());

             assertCloneRepositoryContainsExactlyTheSameInstancesForEntity(cmsEntityToExport);

         } catch (Throwable e) {
             logExportXml(exportURI);
             throw e;
         }
     }

     private void assertCloneRepositoryContainsExactlyTheSameInstancesForEntity(CmsEntityType cmsEntityToExport)
             throws Throwable {

         switch (cmsEntityToExport) {
         case REPOSITORY_USER:
             assertCloneRepositoryContainsExactlyTheSameRepositoryUsers();
             break;
         case ORGANIZATION_SPACE:
             assertCloneRepositoryContainsExactlyTheSameOrganizationSpace();
             break;
         case TAXONOMY:
             assertCloneRepositoryContainsExactlyTheSameTaxonomies();
             break;
         case SPACE:
             assertCloneRepositoryContainsExactlyTheSameSpaces();
             break;
         case OBJECT:
             assertCloneRepositoryContainsExactlyTheSameContentObjects();
             break;
         case REPOSITORY:
             assertCloneRepositoryContainsExactlyTheSameRepositoryUsers();
             assertCloneRepositoryContainsExactlyTheSameOrganizationSpace();
             assertCloneRepositoryContainsExactlyTheSameTaxonomies();
             assertCloneRepositoryContainsExactlyTheSameContentObjects();
             assertCloneRepositoryContainsExactlyTheSameSpaces();
             break;

         default:
             break;
         }

     }

     private void assertCloneRepositoryContainsExactlyTheSameContentObjects() throws Throwable {
         ContentObjectCriteria newContentObjectCriteria = CmsCriteriaFactory.newContentObjectCriteria();
         newContentObjectCriteria.doNotCacheResults();
         newContentObjectCriteria.getRenderProperties().renderAllContentObjectProperties(true);
         newContentObjectCriteria.addOrderProperty("profile.title", Order.descending);

         loginToTestRepositoryAsSystem();
         CmsOutcome<ContentObject> sourceOutcome = contentService.searchContentObjects(newContentObjectCriteria,
                 ResourceRepresentationType.CONTENT_OBJECT_LIST);

         loginToCloneRepositoryAsSystem();
         CmsOutcome<ContentObject> targetOutcome = contentService.searchContentObjects(newContentObjectCriteria,
                 ResourceRepresentationType.CONTENT_OBJECT_LIST);

         repositoryContentValidator.compareContentObjectOutcome(sourceOutcome, targetOutcome);

     }

     private void assertCloneRepositoryContainsExactlyTheSameSpaces() {
         SpaceCriteria newSpaceCriteria = CmsCriteriaFactory.newSpaceCriteria();
         newSpaceCriteria.doNotCacheResults();
         newSpaceCriteria.getRenderProperties().renderAllContentObjectProperties(true);

         loginToTestRepositoryAsSystem();
         newSpaceCriteria.addAncestorSpaceIdEqualsCriterion(spaceService.getOrganizationSpace().getId());
         CmsOutcome<Space> sourceSpaces = spaceService.searchSpaces(newSpaceCriteria,
                 ResourceRepresentationType.SPACE_LIST);

         loginToCloneRepositoryAsSystem();
         newSpaceCriteria.reset();
         newSpaceCriteria.doNotCacheResults();
         newSpaceCriteria.getRenderProperties().renderAllContentObjectProperties(true);
         newSpaceCriteria.addAncestorSpaceIdEqualsCriterion(spaceService.getOrganizationSpace().getId());
         CmsOutcome<Space> targetSpaces = spaceService.searchSpaces(newSpaceCriteria,
                 ResourceRepresentationType.SPACE_LIST);

         repositoryContentValidator.compareSpaceList(sourceSpaces.getResults(), targetSpaces.getResults(), true,
                 false, false);

     }

     private void assertCloneRepositoryContainsExactlyTheSameRepositoryUsers() {

         RepositoryUserCriteria newRepositoryUserCriteria = CmsCriteriaFactory.newRepositoryUserCriteria();
         newRepositoryUserCriteria.doNotCacheResults();
         newRepositoryUserCriteria.getRenderProperties().renderAllContentObjectProperties(true);

         loginToTestRepositoryAsSystem();
         List<RepositoryUser> sourceRepositoryUsers = repositoryUserService
                 .searchRepositoryUsers(newRepositoryUserCriteria);

         loginToCloneRepositoryAsSystem();
         List<RepositoryUser> targetRepositoryUsers = repositoryUserService
                 .searchRepositoryUsers(newRepositoryUserCriteria);

         repositoryContentValidator.compareRepositoryUserList(sourceRepositoryUsers, targetRepositoryUsers);

     }

     private void assertCloneRepositoryContainsExactlyTheSameTaxonomies() {

         loginToTestRepositoryAsSystem();
         CmsOutcome<Taxonomy> sourceTaxonomies = taxonomyService
                 .getAllTaxonomies(ResourceRepresentationType.TAXONOMY_LIST, FetchLevel.FULL, false);

         loginToCloneRepositoryAsSystem();
         CmsOutcome<Taxonomy> targetTaxonomies = taxonomyService
                 .getAllTaxonomies(ResourceRepresentationType.TAXONOMY_LIST, FetchLevel.FULL, false);

         repositoryContentValidator.compareTaxonomyLists(sourceTaxonomies.getResults(),
                 targetTaxonomies.getResults());

     }

     private void assertCloneRepositoryContainsExactlyTheSameOrganizationSpace() {

         loginToTestRepositoryAsSystem();
         Space sourceOrganizationSpace = spaceService.getOrganizationSpace();

         loginToCloneRepositoryAsSystem();
         Space targetOrganizationSpace = spaceService.getOrganizationSpace();

         repositoryContentValidator.compareSpaces(sourceOrganizationSpace, targetOrganizationSpace, true, true, true,
                 false, true);

     }

     protected void validateExportXml(URI exportURI) throws Exception {

         InputStream sourceInputStream = null;

         try {

             logExportXml(exportURI);

             sourceInputStream = contentSourceExtractor.extractStream(exportURI);

             jaxbValidationUtils.validateUsingSAX(sourceInputStream);

         } catch (Exception e) {
             logExportXml(exportURI);
             throw e;
         } finally {
             IOUtils.closeQuietly(sourceInputStream);
         }
     }

     private void logExportXml(URI exportURI) throws IOException, Exception {

         final String xml = IOUtils.toString(contentSourceExtractor.extractStream(exportURI));

         try {
             logger.debug(TestUtils.prettyPrintXml(xml));
         } catch (Exception e) {
             logger.error(xml, "While pretty printing");
             throw e;
         }
     }

     protected ImportReport importExportedEntityToCloneRepository(URI exportURI, ImportConfiguration configuration)
             throws InterruptedException, ExecutionException {

         loginToCloneRepositoryAsSystem();

         long timeStart = System.currentTimeMillis();

         Future<ImportReport> importReportFuture = importDao.importRepositoryContentFromURI(exportURI,
                 configuration);

         while (!importReportFuture.isDone()) {
             final long timePassed = System.currentTimeMillis() - timeStart;
             Assert.assertTrue(timePassed < (5 * 60 * 1000), "Import does not seem to have finished.");

         }

         return importReportFuture.get();
     }

protected URI retrieveUROfExportOutcome(SerializationReport exportReport)
      throws MalformedURLException {
   File exportXml = new File(exportReport.getAbsolutePath());

   return exportXml.toURI();
}

     protected SerializationReport exportEntity(CmsEntityType cmsEntityToExport,
             SerializationConfiguration serializationConfiguration) throws InterruptedException, ExecutionException {
         long timeStart = System.currentTimeMillis();

         Future<SerializationReport> exportReportFuture = serializationDao
                 .serializeAllInstancesOfEntity(cmsEntityToExport, serializationConfiguration);

         //Wait until export is finished
         while (!exportReportFuture.isDone()) {
             final long timePassed = System.currentTimeMillis() - timeStart;

             Assert.assertTrue(timePassed < (5 * 60 * 1000),
                     "Export does not seem to have finished. Time passed " + timePassed + " ms");
         }

         return exportReportFuture.get();
     }

     protected SerializationReport exportObjects(ContentObjectCriteria contentObjectCriteria,
             SerializationConfiguration serializationConfiguration) throws InterruptedException, ExecutionException {
         long timeStart = System.currentTimeMillis();

         Future<SerializationReport> exportReportFuture = serializationDao
                 .serializeObjectsUsingCriteria(contentObjectCriteria, serializationConfiguration);

         //Wait until export is finished
         while (!exportReportFuture.isDone()) {
             final long timePassed = System.currentTimeMillis() - timeStart;

             Assert.assertTrue(timePassed < (5 * 60 * 1000),
                     "Export does not seem to have finished. Time passed " + timePassed + " ms");
         }

         return exportReportFuture.get();
     }

     protected ContentObject createContentObjectAndPopulateAllProperties(RepositoryUser systemUser,
             String systemName) {
         return createContentObjectAndPopulateAllPropertiesForType(TEST_CONTENT_TYPE, systemUser, systemName);
     }

     protected ContentObject createContentObjectAndPopulateAllPropertiesForType(String contentType,
             RepositoryUser systemUser, String systemName) {
         ContentObject contentObject = createContentObjectForType(contentType, systemUser, systemName);

         try {
             //Fill content object with all possible types of properties
             for (CmsPropertyPath cmsPropertyPath : CmsPropertyPath.values()) {
                 addValueForProperty(contentObject, cmsPropertyPath.getPeriodDelimitedPath());
             }
         } catch (Exception e) {
             throw new CmsException(e);
         }

         return contentObject;

     }

     protected void addValueForProperty(ContentObject contentObject, String propertyPath) throws Exception {
         CmsProperty<?, ?> cmsProperty = contentObject.getCmsProperty(propertyPath);

         boolean multiple = cmsProperty.getPropertyDefinition().isMultiple();

         switch (cmsProperty.getValueType()) {
         case Binary:
             provideValueForSimplePropertyWithValueRange((BinaryProperty) cmsProperty, multiple,
                     Arrays.asList(loadManagedBinaryChannel(logo, cmsProperty.getName()),
                             loadManagedBinaryChannel(logo2, cmsProperty.getName())));
             break;
         case ObjectReference:

             ContentObjectCriteria contentObjectCriteria = CmsCriteriaFactory.newContentObjectCriteria();
             contentObjectCriteria.doNotCacheResults();
             contentObjectCriteria.setOffsetAndLimit(0, 2);

             if (contentObject.getId() != null) {
                 contentObjectCriteria.addIdNotEqualsCriterion(contentObject.getId());
             }

             CmsOutcome<ContentObject> outcome = contentService.searchContentObjects(contentObjectCriteria,
                     ResourceRepresentationType.CONTENT_OBJECT_LIST);

             if (outcome.getCount() > 0) {
                 List<ContentObject> results = new ArrayList<ContentObject>();
                 for (ContentObject co : outcome.getResults()) {
                     results.add(co);
                 }

                 provideValueForSimplePropertyWithValueRange((ObjectReferenceProperty) cmsProperty, multiple,
                         results);
             }

             break;
         case Date:
             provideValueForSimplePropertyWithValueRange((CalendarProperty) cmsProperty, multiple,
                     Arrays.asList(Calendar.getInstance(), Calendar.getInstance()));

             break;
         case Double:
             provideValueForSimplePropertyWithValueRange((DoubleProperty) cmsProperty, multiple,
                     Arrays.asList((double) 1.6, (double) 1.7));
             break;
         case Long:
             provideValueForSimplePropertyWithValueRange((LongProperty) cmsProperty, multiple,
                     Arrays.asList((long) 1.23, (long) 1.34));
             break;
         case Boolean:
             provideValueForSimplePropertyWithValueRange((BooleanProperty) cmsProperty, multiple,
                     Arrays.asList(false, true));
             break;
         case String:
             provideValueForSimplePropertyWithValueRange((StringProperty) cmsProperty, multiple,
                     Arrays.asList("Test<b>Value</b>", "TestValue"));
             break;
         case TopicReference:

             TopicCriteria topicCriteria = CmsCriteriaFactory.newTopicCriteria();
             topicCriteria.doNotCacheResults();
             topicCriteria.setOffsetAndLimit(0, 2);

             CmsOutcome<Topic> topics = topicService.searchTopics(topicCriteria,
                     ResourceRepresentationType.TOPIC_LIST);

             if (topics.getCount() > 0) {
                 provideValueForSimplePropertyWithValueRange((TopicReferenceProperty) cmsProperty, multiple,
                         topics.getResults());
             }

             break;

         default:
             break;
         }

     }

     private <T> void provideValueForSimplePropertyWithValueRange(SimpleCmsProperty<T, ?, ?> cmsProperty,
             boolean multiple, List<T> alternativeValues) {
         Map<T, Localization> valueRange = ((SimpleCmsProperty<T, ?, ?>) cmsProperty).getPropertyDefinition()
                 .getValueEnumeration();
         if (valueRange != null && !valueRange.isEmpty()) {
             final Iterator<T> valueRangeIterator = valueRange.keySet().iterator();

             ((SimpleCmsProperty<T, ?, ?>) cmsProperty).addSimpleTypeValue(valueRangeIterator.next());

             if (multiple) {
                 if (valueRangeIterator.hasNext()) {
                     ((SimpleCmsProperty<T, ?, ?>) cmsProperty).addSimpleTypeValue(valueRangeIterator.next());
                 } else {
                     ((SimpleCmsProperty<T, ?, ?>) cmsProperty).addSimpleTypeValue(alternativeValues.get(0));
                 }
             }
         } else {
             ((SimpleCmsProperty<T, ?, ?>) cmsProperty).addSimpleTypeValue(alternativeValues.get(0));

             if (multiple) {
                 ((SimpleCmsProperty<T, ?, ?>) cmsProperty).addSimpleTypeValue(alternativeValues.get(0));
             }
         }
     }

     protected Topic createRootTopicForSubjectTaxonomy(String topicName) {

         Topic topic = JAXBTestUtils.createTopic(topicName,
                 CmsRepositoryEntityFactoryForActiveClient.INSTANCE.getFactory().newTopic(), getSystemUser());
         topic.setTaxonomy(getSubjectTaxonomy());

         topic = topicService.save(topic);
         markTopicForRemoval(topic);

         return topic;
     }

     protected Topic createTopic(String topicName, Topic parentTopic) {

         Topic topic = JAXBTestUtils.createTopic(topicName,
                 CmsRepositoryEntityFactoryForActiveClient.INSTANCE.getFactory().newTopic(), getSystemUser());
         topic.setTaxonomy(getSubjectTaxonomy());

         parentTopic.addChild(topic);

         topic = topicService.save(topic);
         markTopicForRemoval(topic);

         return topic;
     }

     protected Space createRootSpaceForOrganizationSpace(String spaceName) {

         Space space = JAXBTestUtils.createSpace(spaceName,
                 CmsRepositoryEntityFactoryForActiveClient.INSTANCE.getFactory().newSpace(), getSystemUser());
         space.setParent(spaceService.getOrganizationSpace());

         space = spaceService.save(space);
         markSpaceForRemoval(space);

         return space;
     }

     protected Space createSpace(String spaceName, Space parentSpace) {

         Space space = JAXBTestUtils.createSpace(spaceName,
                 CmsRepositoryEntityFactoryForActiveClient.INSTANCE.getFactory().newSpace(), getSystemUser());

         parentSpace.addChild(space);

         space = spaceService.save(space);

         return space;
     }

     protected String generateExpectedValueForOutputFormat(String attributeName, String attributeValue,
             ResourceRepresentationType<?> resourceRepresentationType) {

         if (resourceRepresentationType.equals(ResourceRepresentationType.XML)) {
             return attributeName + "=\"" + attributeValue + "\"";
         } else if (resourceRepresentationType.equals(ResourceRepresentationType.JSON)) {
             return "\"" + attributeName + "\":\"" + attributeValue + "\"";
         } else {
             return attributeName + "\"" + attributeValue + "\"";
         }
     }

     protected Space getOrganizationSpace() {
         return spaceService.getOrganizationSpace();
     }

     protected void logTimeElapsed(String message, long startTime, String... args) {
         logger.debug(message, new Object[] {
                 DurationFormatUtils.formatDurationHMS(System.currentTimeMillis() - startTime), args });
     }

     protected String removeWhitespacesIfNecessary(CmsCriteria cmsCriteria, String xmlOrJson) {

         if (xmlOrJson != null && cmsCriteria.getRenderProperties().isPrettyPrintEnabled()) {
             return StringUtils.deleteWhitespace(xmlOrJson);
         }

         return xmlOrJson;
     }

     protected String removeWhitespacesIfNecessary(String xmlOrJson) {

         if (xmlOrJson != null && prettyPrint) {
             return StringUtils.deleteWhitespace(xmlOrJson);
         }

         return xmlOrJson;
     }

     protected String convertCalendarToXMLFormat(Calendar calendar, boolean dateTimePattern) {
         if (dateTimePattern) {
             GregorianCalendar gregCalendar = new GregorianCalendar(calendar.getTimeZone());
             gregCalendar.setTimeInMillis(calendar.getTimeInMillis());

             return df.newXMLGregorianCalendar(gregCalendar).toXMLFormat();
         } else {
             return df.newXMLGregorianCalendarDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, // Calendar.MONTH is zero based, XSD Date datatype's month field starts
                     //   with JANUARY as 1.
                     calendar.get(Calendar.DAY_OF_MONTH), DatatypeConstants.FIELD_UNDEFINED).toXMLFormat();
         }
     }

 }