001/* 002 * Copyright (c) 2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Nuxeo - initial API and implementation 011 * 012 */ 013 014package org.nuxeo.ecm.core.io.impl.plugins; 015 016import java.io.IOException; 017import java.util.ArrayList; 018import java.util.LinkedList; 019import java.util.List; 020 021import org.nuxeo.common.utils.Path; 022import org.nuxeo.ecm.core.api.CoreSession; 023import org.nuxeo.ecm.core.api.DocumentModel; 024import org.nuxeo.ecm.core.api.DocumentRef; 025import org.nuxeo.ecm.core.api.DocumentTreeIterator; 026import org.nuxeo.ecm.core.io.DocumentReader; 027import org.nuxeo.ecm.core.io.ExportExtension; 028import org.nuxeo.ecm.core.io.ExportedDocument; 029import org.nuxeo.ecm.core.io.impl.ExportedDocumentImpl; 030 031/** 032 * Compared to the default {@link DocumentReader} implementation this one does handle versions and allows to plug 033 * {@link ExportExtension} 034 * 035 * @since 7.4 036 */ 037public class ExtensibleDocumentTreeReader extends DocumentModelReader { 038 039 protected DocumentTreeIterator iterator; 040 041 protected int pathSegmentsToRemove = 0; 042 043 protected List<DocumentModel> pendingVersions = new LinkedList<DocumentModel>(); 044 045 protected List<ExportExtension> extensions = new ArrayList<ExportExtension>(); 046 047 public static final String VERSION_VIRTUAL_PATH_SEGMENT = "__versions__"; 048 049 public ExtensibleDocumentTreeReader(CoreSession session, DocumentModel root, boolean excludeRoot) { 050 super(session); 051 iterator = new DocumentTreeIterator(session, root, excludeRoot); 052 pathSegmentsToRemove = root.getPath().segmentCount() - (excludeRoot ? 0 : 1); 053 } 054 055 public ExtensibleDocumentTreeReader(CoreSession session, DocumentRef root) { 056 this(session, session.getDocument(root)); 057 } 058 059 public ExtensibleDocumentTreeReader(CoreSession session, DocumentModel root) { 060 this(session, root, false); 061 } 062 063 public void registerExtension(ExportExtension ext) { 064 extensions.add(ext); 065 } 066 067 @Override 068 public void close() { 069 super.close(); 070 iterator.reset(); 071 iterator = null; 072 } 073 074 @Override 075 public ExportedDocument read() throws IOException { 076 077 DocumentModel docModel = null; 078 if (pendingVersions.size() > 0) { 079 docModel = pendingVersions.remove(0); 080 } else { 081 if (iterator.hasNext()) { 082 docModel = iterator.next(); 083 try { 084 List<DocumentModel> versions = session.getVersions(docModel.getRef()); 085 if (!versions.isEmpty()) { 086 pendingVersions.addAll(0, versions); 087 } 088 } catch (Exception e) { 089 throw new IOException("Unable to get versions", e); 090 } 091 } 092 } 093 094 ExportedDocumentImpl result = null; 095 if (docModel != null) { 096 if (pathSegmentsToRemove > 0) { 097 // remove unwanted leading segments 098 result = new ExportedDocumentImpl(docModel, 099 docModel.getPath().removeFirstSegments(pathSegmentsToRemove), inlineBlobs); 100 } else { 101 result = new ExportedDocumentImpl(docModel, inlineBlobs); 102 } 103 104 // flag versions 105 if (docModel.isVersion()) { 106 Path path = docModel.getPath().append(VERSION_VIRTUAL_PATH_SEGMENT).append(docModel.getVersionLabel()); 107 if (pathSegmentsToRemove > 0) { 108 path = path.removeFirstSegments(pathSegmentsToRemove); 109 } 110 result.setPath(path); 111 } 112 113 try { 114 for (ExportExtension ext : extensions) { 115 ext.updateExport(docModel, result); 116 } 117 } catch (Exception e) { 118 throw new IOException("Unable to process versions", e); 119 } 120 } 121 return result; 122 } 123 124}