001/*
002 * (C) Copyright 2014-2018 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     annejubert
018 */
019package org.nuxeo.io.fsexporter;
020
021import java.io.File;
022import java.io.IOException;
023import java.io.Serializable;
024import java.util.Date;
025import java.util.HashMap;
026import java.util.List;
027import java.util.Map;
028
029import org.apache.commons.lang3.StringUtils;
030import org.nuxeo.ecm.core.api.Blob;
031import org.nuxeo.ecm.core.api.CoreSession;
032import org.nuxeo.ecm.core.api.DocumentModel;
033import org.nuxeo.ecm.core.api.DocumentModelList;
034import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
035import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
036import org.nuxeo.ecm.platform.query.api.PageProvider;
037import org.nuxeo.ecm.platform.query.api.PageProviderService;
038import org.nuxeo.ecm.platform.query.core.CoreQueryPageProviderDescriptor;
039import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider;
040import org.nuxeo.runtime.api.Framework;
041
042public class DefaultExporterPlugin implements FSExporterPlugin {
043
044    @Override
045    public DocumentModelList getChildren(CoreSession session, DocumentModel doc, String customQuery) {
046        Map<String, Serializable> props = new HashMap<>();
047        props.put(CoreQueryDocumentPageProvider.CORE_SESSION_PROPERTY, (Serializable) session);
048
049        String query;
050        // if the user gives a query, we build a new Page Provider with the query provided
051        if (StringUtils.isNotBlank(customQuery)) {
052            if (customQuery.toLowerCase().contains(" where")) {
053                query = customQuery + " AND ecm:parentId = ?";
054            } else {
055                query = customQuery + " where ecm:parentId = ?";
056            }
057        } else {
058            query = "SELECT * FROM Document WHERE ecm:parentId = ? AND ecm:mixinType !='HiddenInNavigation' AND ecm:isVersion = 0 AND ecm:isTrashed = 0";
059        }
060        CoreQueryPageProviderDescriptor desc = new CoreQueryPageProviderDescriptor();
061        desc.setPattern(query);
062
063        PageProviderService ppService = Framework.getService(PageProviderService.class);
064        @SuppressWarnings("unchecked")
065        PageProvider<DocumentModel> pp = (PageProvider<DocumentModel>) ppService.getPageProvider("customPP", desc, null,
066                null, null, null, props, new Object[] { doc.getId() });
067
068        int countPages = 1;
069        // get all the documents of the first page
070        DocumentModelList children = new DocumentModelListImpl(pp.getCurrentPage());
071        // if there is more than one page, get the children of all the other pages and put into one list
072        if (pp.getNumberOfPages() > 1) {
073            while (countPages < pp.getNumberOfPages()) {
074                pp.nextPage();
075                List<DocumentModel> childrenTemp = pp.getCurrentPage();
076                children.addAll(childrenTemp);
077                countPages++;
078            }
079        }
080        // return the complete list of documents
081        return children;
082    }
083
084    @Override
085    public File serialize(CoreSession session, DocumentModel docfrom, String fsPath) throws IOException {
086        File folder;
087        File newFolder = null;
088        folder = new File(fsPath);
089
090        // if target directory doesn't exist, create it
091        if (!folder.exists()) {
092            folder.mkdir();
093        }
094
095        if ("/".equals(docfrom.getPathAsString())) {
096            // we do not serialize the root document
097            return folder;
098        }
099
100        if (docfrom.hasFacet("Folderish")) {
101            newFolder = new File(fsPath + "/" + docfrom.getName());
102            newFolder.mkdir();
103        }
104
105        // get all the blobs of the blob holder
106        BlobHolder myblobholder = docfrom.getAdapter(BlobHolder.class);
107        if (myblobholder != null) {
108            java.util.List<Blob> listblobs = myblobholder.getBlobs();
109            int i = 1;
110            for (Blob blob : listblobs) {
111                // call the method to determine the name of the exported file
112                String FileNameToExport = getFileName(blob, docfrom, folder, i);
113                // export the file to the target file system
114                File target = new File(folder, FileNameToExport);
115                blob.transferTo(target);
116                i++;
117            }
118        }
119        if (newFolder != null) {
120            folder = newFolder;
121        }
122        return folder;
123    }
124
125    protected String getFileName(Blob blob, DocumentModel docfrom, File folder, int i) {
126        String prefix = "";
127        // if not principal file, prefix = name of the file which contains the blobs
128        if (i != 1) {
129            prefix = docfrom.getName() + "-";
130        }
131
132        // if already existing file, prefix with "timestamp"
133        File alreadyExistingBlob = new File(folder, prefix + blob.getFilename());
134
135        if (alreadyExistingBlob.exists()) {
136            prefix = String.valueOf(new Date().getTime()) + "-" + prefix;
137        }
138
139        return prefix + blob.getFilename();
140    }
141}