001/*
002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo
016 */
017
018package org.nuxeo.ecm.platform.publisher.remoting.server;
019
020import org.nuxeo.ecm.core.api.DocumentLocation;
021import org.nuxeo.ecm.core.api.DocumentModel;
022import org.nuxeo.ecm.core.api.PathRef;
023import org.nuxeo.ecm.platform.publisher.api.PublicationNode;
024import org.nuxeo.ecm.platform.publisher.api.PublicationTree;
025import org.nuxeo.ecm.platform.publisher.api.PublishedDocument;
026import org.nuxeo.ecm.platform.publisher.impl.core.SectionPublicationTree;
027import org.nuxeo.ecm.platform.publisher.remoting.marshaling.ExtendedDocumentLocation;
028import org.nuxeo.ecm.platform.publisher.remoting.marshaling.basic.BasicPublishedDocument;
029
030import java.util.ArrayList;
031import java.util.List;
032import java.util.Map;
033
034/**
035 * {@link PublicationTree} implementation that supports having plain Documents directly inside the sections. This is
036 * typically used for Remote {@link PublicationTree} implementation that will store proxies for locally published
037 * documents and complete {@link DocumentModel} for remote published Documents.
038 *
039 * @author tiry
040 */
041public class CoreTreeWithExternalDocs extends SectionPublicationTree implements PublicationTree {
042
043    private static final long serialVersionUID = 1L;
044
045    @Override
046    public List<PublishedDocument> getExistingPublishedDocument(DocumentLocation docLoc) {
047
048        List<PublishedDocument> publishedDocs = new ArrayList<PublishedDocument>();
049
050        if (docLoc instanceof ExtendedDocumentLocation) {
051            // remote proxy management
052            ExtendedDocumentLocation xDocLoc = (ExtendedDocumentLocation) docLoc;
053
054            String xsrv = xDocLoc.getOriginalServer();
055            // String source = xDocLoc.getServerName() + "@" + srv + ":" +
056            // xDocLoc.getDocRef().toString();
057            String source = xDocLoc.toString();
058            List<DocumentModel> foundDocs = findDocumentsCommingFromExternalRef(treeRoot, source);
059
060            for (DocumentModel doc : foundDocs) {
061                // publishedDocs.add(new
062                // ExternalCorePublishedDocument(doc));
063                publishedDocs.add(factory.wrapDocumentModel(doc));
064            }
065        } else {
066            // std proxy management
067            if (getCoreSession().getRepositoryName().equals(docLoc.getServerName())) {
068                // same repo publishing
069                publishedDocs.addAll(super.getExistingPublishedDocument(docLoc));
070            }
071        }
072        return publishedDocs;
073    }
074
075    protected List<DocumentModel> findDocumentsCommingFromExternalRef(DocumentModel root, String extRef)
076            {
077        // XXX dummy impl : use Relations or Search to avoid this !!!!
078
079        List<DocumentModel> docs = new ArrayList<DocumentModel>();
080
081        for (DocumentModel child : getCoreSession().getChildren(root.getRef())) {
082            if (child.isFolder()) {
083                docs.addAll(findDocumentsCommingFromExternalRef(child, extRef));
084            } else {
085                if (extRef.equals(child.getProperty("dublincore", "source"))) {
086                    docs.add(child);
087                }
088            }
089        }
090        return docs;
091
092    }
093
094    @Override
095    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode) {
096        ExternalCorePublishedDocument publishedDocument = (ExternalCorePublishedDocument) factory.publishDocument(doc,
097                targetNode);
098        return publishedDocument;
099    }
100
101    @Override
102    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode, Map<String, String> params)
103            {
104        ExternalCorePublishedDocument publishedDocument = (ExternalCorePublishedDocument) factory.publishDocument(doc,
105                targetNode, params);
106        return publishedDocument;
107    }
108
109    @Override
110    public void unpublish(PublishedDocument publishedDocument) {
111        if (publishedDocument instanceof BasicPublishedDocument
112                || publishedDocument instanceof ExternalCorePublishedDocument) {
113            String source = publishedDocument.getSourceRepositoryName() + "@" + publishedDocument.getSourceServer()
114                    + ":" + publishedDocument.getSourceDocumentRef();
115            List<DocumentModel> foundDocs = findDocumentsCommingFromExternalRef(treeRoot, source);
116            for (DocumentModel doc : foundDocs) {
117                if (doc.getPathAsString().equals(publishedDocument.getPath())) {
118                    getCoreSession().removeDocument(doc.getRef());
119                    getCoreSession().save();
120                    break;
121                }
122            }
123        } else {
124            super.unpublish(publishedDocument);
125        }
126    }
127
128    @Override
129    public void unpublish(DocumentModel doc, PublicationNode targetNode) {
130        PublicationNode realPublciationNode = getNodeByPath(targetNode.getPath());
131        List<PublishedDocument> publishedDocuments = getPublishedDocumentInNode(realPublciationNode);
132        String source = (String) doc.getProperty("dublincore", "source");
133        for (PublishedDocument publishedDocument : publishedDocuments) {
134            String publishedDocumentSource = publishedDocument.getSourceRepositoryName() + "@"
135                    + publishedDocument.getSourceServer() + ":" + publishedDocument.getSourceDocumentRef();
136            if (source.equals(publishedDocumentSource)) {
137                getCoreSession().removeDocument(new PathRef(publishedDocument.getPath()));
138                break;
139            }
140        }
141    }
142
143    @Override
144    public PublishedDocument wrapToPublishedDocument(DocumentModel documentModel) {
145        return new ExternalCorePublishedDocument(documentModel);
146    }
147
148}