/*
* Copyright (c) 2015 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nuxeo - initial API and implementation
*
*/
package org.nuxeo.ecm.core.io.impl.plugins;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.nuxeo.common.utils.Path;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentRef;
import org.nuxeo.ecm.core.api.DocumentTreeIterator;
import org.nuxeo.ecm.core.io.DocumentReader;
import org.nuxeo.ecm.core.io.ExportExtension;
import org.nuxeo.ecm.core.io.ExportedDocument;
import org.nuxeo.ecm.core.io.impl.ExportedDocumentImpl;
/**
* Compared to the default {@link DocumentReader} implementation this one does handle versions and allows to plug
* {@link ExportExtension}
*
* @since 7.4
*/
public class ExtensibleDocumentTreeReader extends DocumentModelReader {
protected DocumentTreeIterator iterator;
protected int pathSegmentsToRemove = 0;
protected List<DocumentModel> pendingVersions = new LinkedList<DocumentModel>();
protected List<ExportExtension> extensions = new ArrayList<ExportExtension>();
public static final String VERSION_VIRTUAL_PATH_SEGMENT = "__versions__";
public ExtensibleDocumentTreeReader(CoreSession session, DocumentModel root, boolean excludeRoot) {
super(session);
iterator = new DocumentTreeIterator(session, root, excludeRoot);
pathSegmentsToRemove = root.getPath().segmentCount() - (excludeRoot ? 0 : 1);
}
public ExtensibleDocumentTreeReader(CoreSession session, DocumentRef root) {
this(session, session.getDocument(root));
}
public ExtensibleDocumentTreeReader(CoreSession session, DocumentModel root) {
this(session, root, false);
}
public void registerExtension(ExportExtension ext) {
extensions.add(ext);
}
@Override
public void close() {
super.close();
iterator.reset();
iterator = null;
}
@Override
public ExportedDocument read() throws IOException {
DocumentModel docModel = null;
if (pendingVersions.size() > 0) {
docModel = pendingVersions.remove(0);
} else {
if (iterator.hasNext()) {
docModel = iterator.next();
try {
List<DocumentModel> versions = session.getVersions(docModel.getRef());
if (!versions.isEmpty()) {
pendingVersions.addAll(0, versions);
}
} catch (Exception e) {
throw new IOException("Unable to get versions", e);
}
}
}
ExportedDocumentImpl result = null;
if (docModel != null) {
if (pathSegmentsToRemove > 0) {
// remove unwanted leading segments
result = new ExportedDocumentImpl(docModel,
docModel.getPath().removeFirstSegments(pathSegmentsToRemove), inlineBlobs);
} else {
result = new ExportedDocumentImpl(docModel, inlineBlobs);
}
// flag versions
if (docModel.isVersion()) {
Path path = docModel.getPath().append(VERSION_VIRTUAL_PATH_SEGMENT).append(docModel.getVersionLabel());
if (pathSegmentsToRemove > 0) {
path = path.removeFirstSegments(pathSegmentsToRemove);
}
result.setPath(path);
}
try {
for (ExportExtension ext : extensions) {
ext.updateExport(docModel, result);
}
} catch (Exception e) {
throw new IOException("Unable to process versions", e);
}
}
return result;
}
}