diff --git a/ccm-cms/src/org/librecms/contentsection/AbstractAssetsExporter.java b/ccm-cms/src/org/librecms/contentsection/AbstractAssetsExporter.java
new file mode 100644
index 000000000..87d857a55
--- /dev/null
+++ b/ccm-cms/src/org/librecms/contentsection/AbstractAssetsExporter.java
@@ -0,0 +1,37 @@
+package org.librecms.contentsection;
+
+import com.arsdigita.cms.Asset;
+import com.arsdigita.kernel.KernelConfig;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.core.AbstractCcmObjectsExporter;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author Jens Pelzetter
+ * @param
+ */
+public abstract class AbstractAssetsExporter
+ extends AbstractCcmObjectsExporter {
+
+ @Override
+ protected final void exportObjectProperties(final T asset,
+ final JsonGenerator jsonGenerator)
+ throws IOException {
+
+ jsonGenerator.writeObjectFieldStart("title");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ asset.getName());
+ jsonGenerator.writeEndObject();
+
+ exportAssetProperties(asset, jsonGenerator);
+ }
+
+ protected abstract void exportAssetProperties(T asset,
+ JsonGenerator jsonGenerator)
+ throws IOException;
+
+}
diff --git a/ccm-cms/src/org/librecms/contentsection/AbstractBinaryAssetsExporter.java b/ccm-cms/src/org/librecms/contentsection/AbstractBinaryAssetsExporter.java
new file mode 100644
index 000000000..092fbe34a
--- /dev/null
+++ b/ccm-cms/src/org/librecms/contentsection/AbstractBinaryAssetsExporter.java
@@ -0,0 +1,43 @@
+package org.librecms.contentsection;
+
+
+import com.arsdigita.cms.BinaryAsset;
+import com.arsdigita.kernel.KernelConfig;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public abstract class AbstractBinaryAssetsExporter
+ extends AbstractAssetsExporter{
+
+ @Override
+ protected final void exportAssetProperties(
+ final T asset, final JsonGenerator jsonGenerator) throws IOException{
+
+ jsonGenerator.writeObjectFieldStart("description");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ asset.getDescription());
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeStringField("mimeType",
+ asset.getMimeType().toString());
+
+ jsonGenerator.writeStringField("fileName", asset.getName());
+
+ jsonGenerator.writeBinaryField("data", asset.getContent());
+
+ jsonGenerator.writeNumberField("size", asset.getSize());
+
+ exportBinaryAssetProperties(asset, jsonGenerator);
+ }
+
+ protected abstract void exportBinaryAssetProperties(
+ final T asset, final JsonGenerator jsonGenerator) throws IOException;
+
+}
diff --git a/ccm-cms/src/org/librecms/contentsection/AbstractContentItemsExporter.java b/ccm-cms/src/org/librecms/contentsection/AbstractContentItemsExporter.java
new file mode 100644
index 000000000..3259f00ac
--- /dev/null
+++ b/ccm-cms/src/org/librecms/contentsection/AbstractContentItemsExporter.java
@@ -0,0 +1,225 @@
+package org.librecms.contentsection;
+
+import com.arsdigita.cms.ContentBundle;
+import com.arsdigita.cms.ContentPage;
+import com.arsdigita.cms.ItemCollection;
+import com.arsdigita.cms.lifecycle.Lifecycle;
+import com.arsdigita.util.UncheckedWrapperException;
+import com.arsdigita.workflow.simple.Workflow;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.export.AbstractDomainObjectsExporter;
+import org.libreccm.export.IdSequence;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ *
+ * @author Jens Pelzetter
+ * @param
+ */
+public abstract class AbstractContentItemsExporter
+ extends AbstractDomainObjectsExporter {
+
+ @Override
+ protected final List exportDomainObject(final T contentItem,
+ final Path targetDir) {
+
+ final ContentBundle contentBundle = contentItem.getContentBundle();
+
+ if (contentBundle == null) {
+ return Collections.emptyList();
+ }
+
+ final ItemCollection instances = contentBundle.getInstances();
+
+ final String uuid = generateUuid(contentBundle);
+ final String itemUuid = generateUuid(contentBundle.getDraftVersion());
+ final Path targetFilePath = generateTargetFilePath(
+ targetDir, uuid);
+
+ final JsonFactory jsonFactory = new JsonFactory();
+ try (JsonGenerator jsonGenerator = jsonFactory
+ .createGenerator(targetFilePath.toFile(), JsonEncoding.UTF8)) {
+
+ setPrettyPrinter(jsonGenerator);
+
+ jsonGenerator.writeStartObject();
+
+ jsonGenerator.writeNumberField("objectId",
+ IdSequence.getInstance().nextId());
+ jsonGenerator.writeStringField("uuid", uuid);
+ jsonGenerator.writeStringField("displayName",
+ contentBundle.getDisplayName());
+
+ jsonGenerator.writeStringField("itemUuid", itemUuid);
+
+ final Map titles = new HashMap<>();
+ final Map descriptions = new HashMap<>();
+ while (instances.next()) {
+
+ final ContentPage instance = (ContentPage) instances
+ .getContentItem();
+
+ final String lang = instance.getLanguage();
+ final Locale locale = new Locale(lang);
+
+ titles.put(locale, instance.getTitle());
+ descriptions.put(locale, instance.getDescription());
+ }
+
+ instances.rewind();
+
+ jsonGenerator.writeObjectFieldStart("title");
+ for (final Map.Entry title : titles.entrySet()) {
+
+ jsonGenerator.writeStringField(title.getKey().toString(),
+ title.getValue());
+
+ }
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeObjectFieldStart("description");
+ for (final Map.Entry desc : descriptions.entrySet()) {
+
+ jsonGenerator.writeStringField(desc.getKey().toString(),
+ desc.getValue());
+
+ }
+ jsonGenerator.writeEndObject();
+
+ if (contentItem.getVersion() == null) {
+ jsonGenerator.writeStringField("version", "DRAFT");
+ } else {
+ jsonGenerator.writeStringField("version",
+ contentItem.getVersion());
+ }
+
+ final DateTimeFormatter dateTimeFormatter
+ = DateTimeFormatter.ISO_DATE_TIME;
+
+ if (contentItem.getLaunchDate() != null) {
+ final LocalDateTime launchDate = LocalDateTime
+ .ofInstant(contentItem.getLaunchDate().toInstant(),
+ ZoneId.systemDefault());
+ jsonGenerator.writeStringField("launchDate",
+ dateTimeFormatter.format(
+ launchDate));
+ }
+
+ jsonGenerator.writeStringField(
+ "creationDate",
+ dateTimeFormatter.format(
+ LocalDateTime.ofInstant(
+ contentItem.getCreationDate().toInstant(),
+ ZoneId.systemDefault())));
+
+ jsonGenerator.writeStringField(
+ "lastModified",
+ dateTimeFormatter.format(
+ LocalDateTime.ofInstant(
+ contentItem.getLastModifiedDate().toInstant(),
+ ZoneId.systemDefault())));
+
+ final Lifecycle lifecyle = contentItem.getLifecycle();
+ if (lifecyle != null) {
+ jsonGenerator.writeStringField(
+ "lifecycle",
+ generateUuid(contentItem.getLifecycle()));
+ }
+
+ final Workflow workflow = Workflow.getObjectWorkflow(contentItem);
+ if (workflow != null) {
+ jsonGenerator.writeStringField("workflow",
+ generateUuid(workflow));
+ }
+
+ if (contentItem.getCreationUser() != null) {
+ jsonGenerator.writeStringField(
+ "creationUserName",
+ contentItem.getCreationUser().getName());
+ }
+
+ if (contentItem.getLastModifiedUser() != null) {
+ jsonGenerator.writeStringField(
+ "lastModifyingUserName",
+ contentItem.getLastModifiedUser().getName());
+ }
+
+ exportContentItemProperties(contentItem, jsonGenerator);
+
+ final Map> localizedProperties
+ = collectLocalizedValues(
+ instances);
+
+ for (final Map.Entry> property
+ : localizedProperties.entrySet()) {
+
+ jsonGenerator.writeObjectFieldStart(property.getKey());
+
+ for (final Map.Entry localizedValue : property
+ .getValue().entrySet()) {
+
+ jsonGenerator.writeStringField(
+ localizedValue.getKey().toString(),
+ localizedValue.getValue());
+ }
+
+ jsonGenerator.writeEndObject();
+ }
+
+ jsonGenerator.writeEndObject();
+ } catch (IOException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ return Arrays.asList(new String[]{uuid});
+ }
+
+ /**
+ * Exports not localised properties of a content items.
+ *
+ * @param contentItem The item providing the data.
+ * @param jsonGenerator The {@link JsonGenerator} to use.
+ *
+ * @throws IOException
+ */
+ protected abstract void exportContentItemProperties(
+ T contentItem, JsonGenerator jsonGenerator)
+ throws IOException;
+
+ /**
+ * This method is used to collect localised properties. The
+ * {@link #exportDomainObject(com.arsdigita.cms.ContentPage, java.nio.file.Path)}
+ * method takes care for writing the values to the export file. The
+ * properties {@code title} and {@code description} are already handled by
+ * {@link #exportDomainObject(com.arsdigita.cms.ContentPage, java.nio.file.Path)}.
+ *
+ * If the {@code ContentItem} to export does not have any localised
+ * properties the implementation of this method should return an empty map.
+ * The most efficient way to create an empty map is the use
+ * {@link Collections#emptyMap()}.
+ *
+ * @param instances The instances of the content item.
+ *
+ * @return A {@link Map} of {@link Maps} with the localised values. The key
+ * of the outer map is the name of the property, the value are the
+ * localised values. The inner map contains the localised values.
+ * The key of this map is the locale of the value.
+ */
+ protected abstract Map> collectLocalizedValues(
+ ItemCollection instances);
+
+}
diff --git a/ccm-cms/src/org/librecms/contentsection/ContentSectionsExporter.java b/ccm-cms/src/org/librecms/contentsection/ContentSectionsExporter.java
new file mode 100644
index 000000000..71e4810eb
--- /dev/null
+++ b/ccm-cms/src/org/librecms/contentsection/ContentSectionsExporter.java
@@ -0,0 +1,112 @@
+package org.librecms.contentsection;
+
+import com.arsdigita.cms.ContentSection;
+import com.arsdigita.cms.ContentType;
+import com.arsdigita.cms.ContentTypeCollection;
+import com.arsdigita.cms.Folder;
+import com.arsdigita.cms.lifecycle.LifecycleDefinition;
+import com.arsdigita.cms.lifecycle.LifecycleDefinitionCollection;
+import com.arsdigita.kernel.Role;
+import com.arsdigita.kernel.RoleCollection;
+import com.arsdigita.workflow.simple.Task;
+import com.arsdigita.workflow.simple.TaskCollection;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.web.AbstractCcmApplicationsExporter;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ContentSectionsExporter
+ extends AbstractCcmApplicationsExporter {
+
+ @Override
+ public Class exportsType() {
+ return ContentSection.class;
+ }
+
+ @Override
+ public String exportsBaseDataObjectType() {
+ return ContentSection.BASE_DATA_OBJECT_TYPE;
+ }
+
+ @Override
+ public String convertsToType() {
+ return "org.librecms.contentsection.ContentSection";
+ }
+
+ @Override
+ protected void exportApplicationProperties(
+ final ContentSection section,
+ final JsonGenerator jsonGenerator)
+ throws IOException {
+
+ jsonGenerator.writeStringField("label", section.getTitle());
+
+ final Folder rootDocsFolder = section.getRootFolder();
+ final String rootDocsFolderUuid = generateUuid(rootDocsFolder);
+ jsonGenerator.writeStringField("rootDocumentsFolder",
+ rootDocsFolderUuid);
+
+ jsonGenerator.writeStringField("pageResolverClass",
+ section.getPageResolverClassName());
+ jsonGenerator.writeStringField("itemResolverClass",
+ section.getItemResolverClassName());
+ jsonGenerator.writeStringField("templateResolverClass",
+ section.getTemplateResolverClassName());
+ jsonGenerator.writeStringField("xmlGeneratorClass",
+ section.getXMLGeneratorClassName());
+
+ jsonGenerator.writeArrayFieldStart("roles");
+ final RoleCollection roles = section.getGroup().getRoles();
+ while (roles.next()) {
+
+ final Role role = roles.getRole();
+ final String roleUuid = generateUuid(role);
+ jsonGenerator.writeString(roleUuid);
+ }
+ jsonGenerator.writeEndArray();
+
+ jsonGenerator.writeStringField("defaultLocale",
+ section.getDefaultLocale().toString());
+
+ jsonGenerator.writeArrayFieldStart("contentTypes");
+ final ContentTypeCollection types = section.getContentTypes();
+ while (types.next()) {
+
+ final ContentType type = types.getContentType();
+ final String typeUuid = generateUuid(type);
+ jsonGenerator.writeString(typeUuid);
+ }
+ jsonGenerator.writeEndArray();
+
+ final LifecycleDefinitionCollection lifecycleDefs = section
+ .getLifecycleDefinitions();
+ jsonGenerator.writeArrayFieldStart("lifecycleDefinitions");
+ while (lifecycleDefs.next()) {
+ final LifecycleDefinition lifecycleDef = lifecycleDefs
+ .getLifecycleDefinition();
+ final String lifecycleDefUuid = generateUuid(lifecycleDef);
+ jsonGenerator.writeString(lifecycleDefUuid);
+ }
+ jsonGenerator.writeEndArray();
+
+ final TaskCollection workflowTemplates = section.getWorkflowTemplates();
+ jsonGenerator.writeArrayFieldStart("workflowTemplates");
+ while (workflowTemplates.next()) {
+
+ final Task workflowTemplate = workflowTemplates.getTask();
+ final String workflowTemplateUuid = generateUuid(workflowTemplate);
+ jsonGenerator.writeString(workflowTemplateUuid);
+
+ }
+
+ jsonGenerator.writeEndArray();
+ }
+
+}
diff --git a/ccm-cms/src/org/librecms/contentsection/ContentTypesExporter.java b/ccm-cms/src/org/librecms/contentsection/ContentTypesExporter.java
new file mode 100644
index 000000000..fc29da232
--- /dev/null
+++ b/ccm-cms/src/org/librecms/contentsection/ContentTypesExporter.java
@@ -0,0 +1,124 @@
+package org.librecms.contentsection;
+
+import com.arsdigita.cms.ContentSection;
+import com.arsdigita.cms.ContentType;
+import com.arsdigita.kernel.KernelConfig;
+
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.util.UncheckedWrapperException;
+import com.arsdigita.web.WebConfig;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.export.AbstractDomainObjectsExporter;
+import org.libreccm.export.IdSequence;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.UUID;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ContentTypesExporter extends AbstractDomainObjectsExporter {
+
+ @Override
+ public Class exportsType() {
+ return ContentType.class;
+ }
+
+ @Override
+ public String exportsBaseDataObjectType() {
+ return ContentSection.BASE_DATA_OBJECT_TYPE;
+ }
+
+ @Override
+ public String convertsToType() {
+ return "org.librecms.contentsection.ContentType";
+ }
+
+ @Override
+ protected List exportDomainObject(final ContentType contentType,
+ final Path targetDir) {
+
+ final DataCollection contentSectionsCollections = ContentTypesService
+ .getContentSections(contentType);
+
+ final JsonFactory jsonFactory = new JsonFactory();
+
+ final List uuids = new ArrayList<>();
+ while (contentSectionsCollections.next()) {
+
+ final String className = contentType.getClassName();
+ final ContentSection contentSection = new ContentSection(
+ contentSectionsCollections.getDataObject());
+
+ final byte[] uuidSource = String.format(
+ "%s/%s-%s-%s",
+ WebConfig.getInstanceOf().getSiteName(),
+ contentType.getOID().toString(),
+ contentSection.getOID().toString(),
+ className)
+ .getBytes(StandardCharsets.UTF_8);
+ final String uuid = UUID.nameUUIDFromBytes(uuidSource).toString();
+ uuids.add(uuid);
+
+ final String contentSectionUuid = generateUuid(contentSection);
+
+ final Path targetFilePath = targetDir
+ .resolve("org.librecms.contentsection.ContentType")
+ .resolve(String.format("%s.json", uuid));
+ final File targetFile = targetFilePath.toFile();
+
+ try (JsonGenerator jsonGenerator = jsonFactory
+ .createGenerator(targetFile, JsonEncoding.UTF8)) {
+
+ setPrettyPrinter(jsonGenerator);
+
+ jsonGenerator.writeStartObject();
+
+ jsonGenerator.writeNumberField(
+ "objectId",
+ IdSequence.getInstance().nextId());
+ jsonGenerator.writeStringField("uuid", uuid);
+
+ jsonGenerator.writeStringField("contentItemClass",
+ className);
+ jsonGenerator.writeStringField("contentSection",
+ contentSectionUuid);
+
+ jsonGenerator.writeObjectFieldStart("label");;
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ (String) contentType.getLabel().localize(
+ new Locale(KernelConfig
+ .getConfig()
+ .getDefaultLanguage())));
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeObjectFieldStart("description");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ contentType.getDescription());
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeStringField("mode", contentType.getMode());
+
+ jsonGenerator.writeEndObject();
+ } catch(IOException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ }
+
+ return uuids;
+ }
+
+}
diff --git a/ccm-cms/src/org/librecms/contentsection/ContentTypesService.java b/ccm-cms/src/org/librecms/contentsection/ContentTypesService.java
new file mode 100644
index 000000000..fb2f41e76
--- /dev/null
+++ b/ccm-cms/src/org/librecms/contentsection/ContentTypesService.java
@@ -0,0 +1,20 @@
+package org.librecms.contentsection;
+
+import com.arsdigita.cms.ContentType;
+import com.arsdigita.domain.DomainService;
+import com.arsdigita.persistence.DataCollection;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+final class ContentTypesService extends DomainService {
+
+ protected static DataCollection getContentSections(
+ final ContentType section) {
+
+ return (DataCollection) get(section, "associatedContentSectionsForType");
+
+ }
+
+}
diff --git a/ccm-cms/src/org/librecms/contentsection/FoldersExporter.java b/ccm-cms/src/org/librecms/contentsection/FoldersExporter.java
new file mode 100644
index 000000000..4ccfe877e
--- /dev/null
+++ b/ccm-cms/src/org/librecms/contentsection/FoldersExporter.java
@@ -0,0 +1,64 @@
+package org.librecms.contentsection;
+
+import com.arsdigita.cms.ContentSection;
+import com.arsdigita.cms.Folder;
+import com.arsdigita.kernel.KernelConfig;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.core.AbstractCcmObjectsExporter;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class FoldersExporter extends AbstractCcmObjectsExporter {
+
+ @Override
+ protected void exportObjectProperties(final Folder folder,
+ final JsonGenerator jsonGenerator)
+ throws IOException {
+
+ jsonGenerator.writeStringField("uniqueId", generateUuid(folder));
+ jsonGenerator.writeStringField("name", folder.getName());
+
+ final ContentSection section = folder.getContentSection();
+ final String sectionUuid = generateUuid(section);
+ jsonGenerator.writeStringField("contentSection", sectionUuid);
+
+ jsonGenerator.writeObjectFieldStart("title");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ folder.getName());
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeBooleanField("enabled", true);
+ jsonGenerator.writeBooleanField("visible", true);
+ jsonGenerator.writeBooleanField("abstractCategory", true);
+
+ jsonGenerator.writeStringField(
+ "parentCategory",
+ generateUuid(folder.getParent()));
+
+ }
+
+ @Override
+ public Class exportsType() {
+
+ return Folder.class;
+ }
+
+ @Override
+ public String exportsBaseDataObjectType() {
+
+ return Folder.BASE_DATA_OBJECT_TYPE;
+ }
+
+ @Override
+ public String convertsToType() {
+
+ return "org.librecms.contentsection.Folder";
+ }
+
+}
diff --git a/ccm-cms/src/org/librecms/lifecycle/LifecycleDefinitionsExporter.java b/ccm-cms/src/org/librecms/lifecycle/LifecycleDefinitionsExporter.java
new file mode 100644
index 000000000..6bc33edbc
--- /dev/null
+++ b/ccm-cms/src/org/librecms/lifecycle/LifecycleDefinitionsExporter.java
@@ -0,0 +1,103 @@
+package org.librecms.lifecycle;
+
+import com.arsdigita.cms.lifecycle.LifecycleDefinition;
+import com.arsdigita.cms.lifecycle.PhaseDefinitionCollection;
+import com.arsdigita.kernel.KernelConfig;
+import com.arsdigita.util.UncheckedWrapperException;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.export.AbstractDomainObjectsExporter;
+import org.libreccm.export.IdSequence;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class LifecycleDefinitionsExporter
+ extends AbstractDomainObjectsExporter {
+
+ @Override
+ public Class exportsType() {
+ return LifecycleDefinition.class;
+ }
+
+ @Override
+ public String exportsBaseDataObjectType() {
+ return LifecycleDefinition.BASE_DATA_OBJECT_TYPE;
+ }
+
+ @Override
+ public String convertsToType() {
+ return "org.librecms.lifecycle.LifecycleDefinition";
+ }
+
+ @Override
+ protected List exportDomainObject(
+ final LifecycleDefinition lifecycleDefinition, final Path targetDir) {
+
+ final String uuid = generateUuid(lifecycleDefinition);
+
+ final Path targetFilePath = targetDir
+ .resolve("org.librecms.lifecycle.LifecycleDefinition")
+ .resolve(String.format("%s.json", uuid));
+ final File targetFile = targetFilePath.toFile();
+
+ final JsonFactory jsonFactory = new JsonFactory();
+ try (JsonGenerator jsonGenerator = jsonFactory
+ .createGenerator(targetFile, JsonEncoding.UTF8)) {
+
+ setPrettyPrinter(jsonGenerator);
+
+ jsonGenerator.writeStartObject();
+
+ jsonGenerator.writeNumberField("definitionId",
+ IdSequence.getInstance().nextId());
+ jsonGenerator.writeStringField("uuid", uuid);
+
+ jsonGenerator.writeObjectFieldStart("label");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ lifecycleDefinition.getLabel());
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeObjectFieldStart("description");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ lifecycleDefinition.getDescription());
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeStringField(
+ "defaultListener",
+ lifecycleDefinition.getDefaultListener());
+
+ final PhaseDefinitionCollection phaseDefinitions
+ = lifecycleDefinition
+ .getPhaseDefinitions();
+ jsonGenerator.writeStartArray();
+ while (phaseDefinitions.next()) {
+ jsonGenerator
+ .writeString(generateUuid(
+ phaseDefinitions.getPhaseDefinition()));
+ }
+ jsonGenerator.writeEndArray();
+
+ jsonGenerator.writeEndObject();;
+
+ } catch (IOException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ return Arrays.asList(new String[]{uuid});
+
+ }
+
+}
diff --git a/ccm-cms/src/org/librecms/lifecycle/LifecyclesExporter.java b/ccm-cms/src/org/librecms/lifecycle/LifecyclesExporter.java
new file mode 100644
index 000000000..e433c4ea8
--- /dev/null
+++ b/ccm-cms/src/org/librecms/lifecycle/LifecyclesExporter.java
@@ -0,0 +1,111 @@
+package org.librecms.lifecycle;
+
+import com.arsdigita.cms.lifecycle.Lifecycle;
+import com.arsdigita.cms.lifecycle.PhaseCollection;
+import com.arsdigita.util.UncheckedWrapperException;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.export.AbstractDomainObjectsExporter;
+import org.libreccm.export.IdSequence;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class LifecyclesExporter extends AbstractDomainObjectsExporter {
+
+ @Override
+ protected List exportDomainObject(final Lifecycle lifecycle,
+ final Path targetDir) {
+
+ final String uuid = generateUuid(lifecycle);
+
+ final Path targetFilePath = targetDir
+ .resolve("org.libreccm.lifecycle.Lifecycle")
+ .resolve(String.format("%s.json", uuid));
+ final File targetFile = targetFilePath.toFile();
+
+ final JsonFactory jsonFactory = new JsonFactory();
+ try (JsonGenerator jsonGenerator = jsonFactory
+ .createGenerator(targetFile, JsonEncoding.UTF8)) {
+
+ setPrettyPrinter(jsonGenerator);
+
+ jsonGenerator.writeStartObject();
+
+ jsonGenerator.writeNumberField("lifecycleId",
+ IdSequence.getInstance().nextId());
+ jsonGenerator.writeStringField("uuid", uuid);
+
+ final DateTimeFormatter dateTimeFormatter
+ = DateTimeFormatter.ISO_DATE_TIME;
+
+ jsonGenerator.writeStringField(
+ "startDateTime",
+ dateTimeFormatter.format(
+ LocalDateTime.ofInstant(
+ lifecycle.getStartDate().toInstant(),
+ ZoneId.systemDefault())));
+ jsonGenerator.writeStringField(
+ "endDateTime",
+ dateTimeFormatter.format(
+ LocalDateTime.ofInstant(
+ lifecycle.getEndDate().toInstant(),
+ ZoneId.systemDefault())));
+
+ jsonGenerator.writeStringField("listener",
+ lifecycle.getListenerClassName());
+
+ jsonGenerator.writeBooleanField("started", lifecycle.hasBegun());
+ jsonGenerator.writeBooleanField("finished", lifecycle.hasEnded());
+
+ jsonGenerator.writeStringField(
+ "lifecycleDefinition",
+ generateUuid(lifecycle.getLifecycleDefinition()));
+
+ final PhaseCollection phases = lifecycle.getPhases();
+ jsonGenerator.writeStartArray();
+ while (phases.next()) {
+ jsonGenerator.writeString(generateUuid(phases.getPhase()));
+ }
+ jsonGenerator.writeEndArray();
+
+ jsonGenerator.writeEndObject();
+
+ } catch (IOException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ return Arrays.asList(new String[]{uuid});
+ }
+
+ @Override
+ public Class exportsType() {
+
+ return Lifecycle.class;
+ }
+
+ @Override
+ public String exportsBaseDataObjectType() {
+
+ return Lifecycle.BASE_DATA_OBJECT_TYPE;
+ }
+
+ @Override
+ public String convertsToType() {
+
+ return "org.librecms.lifecycle.Lifecycle";
+
+ }
+}
\ No newline at end of file
diff --git a/ccm-cms/src/org/librecms/lifecycle/PhaseDefinitionsExporter.java b/ccm-cms/src/org/librecms/lifecycle/PhaseDefinitionsExporter.java
new file mode 100644
index 000000000..23c108f48
--- /dev/null
+++ b/ccm-cms/src/org/librecms/lifecycle/PhaseDefinitionsExporter.java
@@ -0,0 +1,91 @@
+package org.librecms.lifecycle;
+
+import com.arsdigita.cms.lifecycle.PhaseDefinition;
+import com.arsdigita.kernel.KernelConfig;
+import com.arsdigita.util.UncheckedWrapperException;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.export.AbstractDomainObjectsExporter;
+import org.libreccm.export.IdSequence;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class PhaseDefinitionsExporter
+ extends AbstractDomainObjectsExporter {
+
+ @Override
+ public Class exportsType() {
+ return PhaseDefinition.class;
+ }
+
+ @Override
+ public String exportsBaseDataObjectType() {
+ return PhaseDefinition.BASE_DATA_OBJECT_TYPE;
+ }
+
+ @Override
+ public String convertsToType() {
+ return "org.librecms.lifecycle.PhaseDefinition";
+ }
+
+ @Override
+ protected List exportDomainObject(
+ final PhaseDefinition phaseDefinition, final Path targetDir) {
+
+ final String uuid = generateUuid(phaseDefinition);
+ final Path targetFilePath = targetDir
+ .resolve("org.librecms.lifecycle.PhaseDefinition")
+ .resolve(String.format("%s.json", uuid));
+ final File targetFile = targetFilePath.toFile();
+
+ final JsonFactory jsonFactory = new JsonFactory();
+ try (final JsonGenerator jsonGenerator = jsonFactory
+ .createGenerator(targetFile, JsonEncoding.UTF8)) {
+
+ setPrettyPrinter(jsonGenerator);
+
+ jsonGenerator.writeStartObject();
+
+ jsonGenerator.writeNumberField("definitionId",
+ IdSequence.getInstance().nextId());
+ jsonGenerator.writeStringField("uuid", uuid);
+
+ jsonGenerator.writeObjectFieldStart("label");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ phaseDefinition.getLabel());
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeObjectFieldStart("description");
+ jsonGenerator.writeStringField(
+ KernelConfig.getConfig().getDefaultLanguage(),
+ phaseDefinition.getDescription());
+ jsonGenerator.writeEndObject();
+
+ jsonGenerator.writeNumberField("defaultDelay",
+ phaseDefinition.getDefaultDelay());
+ jsonGenerator.writeNumberField("defaultDuration",
+ phaseDefinition.getDefaultDuration());
+
+ jsonGenerator.writeStringField("defaultListener",
+ phaseDefinition.getDefaultListener());
+
+ jsonGenerator.writeEndObject();
+ } catch (IOException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ return Arrays.asList(new String[]{uuid});
+ }
+
+}
diff --git a/ccm-cms/src/org/librecms/lifecycle/PhasesExporter.java b/ccm-cms/src/org/librecms/lifecycle/PhasesExporter.java
new file mode 100644
index 000000000..f66123262
--- /dev/null
+++ b/ccm-cms/src/org/librecms/lifecycle/PhasesExporter.java
@@ -0,0 +1,98 @@
+package org.librecms.lifecycle;
+
+import com.arsdigita.cms.lifecycle.Phase;
+import com.arsdigita.util.UncheckedWrapperException;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.libreccm.export.AbstractDomainObjectsExporter;
+import org.libreccm.export.IdSequence;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class PhasesExporter extends AbstractDomainObjectsExporter {
+
+ @Override
+ public Class exportsType() {
+ return Phase.class;
+ }
+
+ @Override
+ public String exportsBaseDataObjectType() {
+ return Phase.BASE_DATA_OBJECT_TYPE;
+ }
+
+ @Override
+ public String convertsToType() {
+ return "org.librcms.lifecycle.Phase";
+ }
+
+ @Override
+ protected List exportDomainObject(final Phase phase,
+ final Path targetDir) {
+
+ final String uuid = generateUuid(phase);
+ final Path targetFilePath = targetDir
+ .resolve("org.librecms.lifecycle.Phase")
+ .resolve(String.format("%s.json", uuid));
+ final File targetFile = targetFilePath.toFile();
+
+ final JsonFactory jsonFactory = new JsonFactory();
+ try (JsonGenerator jsonGenerator = jsonFactory
+ .createGenerator(targetFile, JsonEncoding.UTF8)) {
+
+ setPrettyPrinter(jsonGenerator);
+
+ jsonGenerator.writeStartObject();
+
+ jsonGenerator.writeNumberField("phaseId",
+ IdSequence.getInstance().nextId());
+ jsonGenerator.writeStringField("uuid", uuid);
+
+ final DateTimeFormatter dateTimeFormatter
+ = DateTimeFormatter.ISO_DATE_TIME;
+
+ jsonGenerator.writeStringField(
+ "startDateTime",
+ dateTimeFormatter.format(
+ LocalDateTime.ofInstant(phase.getStartDate().toInstant(),
+ ZoneId.systemDefault())));
+
+ jsonGenerator.writeStringField(
+ "endDateTime",
+ dateTimeFormatter.format(
+ LocalDateTime.ofInstant(phase.getEndDate().toInstant(),
+ ZoneId.systemDefault())));
+
+ jsonGenerator.writeStringField("listener",
+ phase.getListenerClassName());
+
+ jsonGenerator.writeBooleanField("started", phase.hasBegun());
+ jsonGenerator.writeBooleanField("finished", phase.hasEnded());
+
+ jsonGenerator.writeStringField(
+ "phaseDefinition",
+ generateUuid(phase.getPhaseDefinition()));
+
+ jsonGenerator.writeEndObject();
+
+ } catch (IOException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ return Arrays.asList(new String[]{uuid});
+ }
+
+}