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);
}