001/*
002 * (C) Copyright 2006-2009 Nuxeo SA (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 *     Nuxeo
018 */
019
020package org.nuxeo.ecm.platform.publisher.remoting.server;
021
022import org.nuxeo.ecm.core.api.DocumentLocation;
023import org.nuxeo.ecm.core.api.DocumentModel;
024import org.nuxeo.ecm.core.api.PathRef;
025import org.nuxeo.ecm.platform.publisher.api.PublicationNode;
026import org.nuxeo.ecm.platform.publisher.api.PublicationTree;
027import org.nuxeo.ecm.platform.publisher.api.PublishedDocument;
028import org.nuxeo.ecm.platform.publisher.impl.core.SectionPublicationTree;
029import org.nuxeo.ecm.platform.publisher.remoting.marshaling.ExtendedDocumentLocation;
030import org.nuxeo.ecm.platform.publisher.remoting.marshaling.basic.BasicPublishedDocument;
031
032import java.util.ArrayList;
033import java.util.List;
034import java.util.Map;
035
036/**
037 * {@link PublicationTree} implementation that supports having plain Documents directly inside the sections. This is
038 * typically used for Remote {@link PublicationTree} implementation that will store proxies for locally published
039 * documents and complete {@link DocumentModel} for remote published Documents.
040 *
041 * @author tiry
042 */
043public class CoreTreeWithExternalDocs extends SectionPublicationTree implements PublicationTree {
044
045    private static final long serialVersionUID = 1L;
046
047    @Override
048    public List<PublishedDocument> getExistingPublishedDocument(DocumentLocation docLoc) {
049
050        List<PublishedDocument> publishedDocs = new ArrayList<PublishedDocument>();
051
052        if (docLoc instanceof ExtendedDocumentLocation) {
053            // remote proxy management
054            ExtendedDocumentLocation xDocLoc = (ExtendedDocumentLocation) docLoc;
055
056            String xsrv = xDocLoc.getOriginalServer();
057            // String source = xDocLoc.getServerName() + "@" + srv + ":" +
058            // xDocLoc.getDocRef().toString();
059            String source = xDocLoc.toString();
060            List<DocumentModel> foundDocs = findDocumentsCommingFromExternalRef(treeRoot, source);
061
062            for (DocumentModel doc : foundDocs) {
063                // publishedDocs.add(new
064                // ExternalCorePublishedDocument(doc));
065                publishedDocs.add(factory.wrapDocumentModel(doc));
066            }
067        } else {
068            // std proxy management
069            if (getCoreSession().getRepositoryName().equals(docLoc.getServerName())) {
070                // same repo publishing
071                publishedDocs.addAll(super.getExistingPublishedDocument(docLoc));
072            }
073        }
074        return publishedDocs;
075    }
076
077    protected List<DocumentModel> findDocumentsCommingFromExternalRef(DocumentModel root, String extRef)
078            {
079        // XXX dummy impl : use Relations or Search to avoid this !!!!
080
081        List<DocumentModel> docs = new ArrayList<DocumentModel>();
082
083        for (DocumentModel child : getCoreSession().getChildren(root.getRef())) {
084            if (child.isFolder()) {
085                docs.addAll(findDocumentsCommingFromExternalRef(child, extRef));
086            } else {
087                if (extRef.equals(child.getProperty("dublincore", "source"))) {
088                    docs.add(child);
089                }
090            }
091        }
092        return docs;
093
094    }
095
096    @Override
097    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode) {
098        ExternalCorePublishedDocument publishedDocument = (ExternalCorePublishedDocument) factory.publishDocument(doc,
099                targetNode);
100        return publishedDocument;
101    }
102
103    @Override
104    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode, Map<String, String> params)
105            {
106        ExternalCorePublishedDocument publishedDocument = (ExternalCorePublishedDocument) factory.publishDocument(doc,
107                targetNode, params);
108        return publishedDocument;
109    }
110
111    @Override
112    public void unpublish(PublishedDocument publishedDocument) {
113        if (publishedDocument instanceof BasicPublishedDocument
114                || publishedDocument instanceof ExternalCorePublishedDocument) {
115            String source = publishedDocument.getSourceRepositoryName() + "@" + publishedDocument.getSourceServer()
116                    + ":" + publishedDocument.getSourceDocumentRef();
117            List<DocumentModel> foundDocs = findDocumentsCommingFromExternalRef(treeRoot, source);
118            for (DocumentModel doc : foundDocs) {
119                if (doc.getPathAsString().equals(publishedDocument.getPath())) {
120                    getCoreSession().removeDocument(doc.getRef());
121                    getCoreSession().save();
122                    break;
123                }
124            }
125        } else {
126            super.unpublish(publishedDocument);
127        }
128    }
129
130    @Override
131    public void unpublish(DocumentModel doc, PublicationNode targetNode) {
132        PublicationNode realPublciationNode = getNodeByPath(targetNode.getPath());
133        List<PublishedDocument> publishedDocuments = getPublishedDocumentInNode(realPublciationNode);
134        String source = (String) doc.getProperty("dublincore", "source");
135        for (PublishedDocument publishedDocument : publishedDocuments) {
136            String publishedDocumentSource = publishedDocument.getSourceRepositoryName() + "@"
137                    + publishedDocument.getSourceServer() + ":" + publishedDocument.getSourceDocumentRef();
138            if (source.equals(publishedDocumentSource)) {
139                getCoreSession().removeDocument(new PathRef(publishedDocument.getPath()));
140                break;
141            }
142        }
143    }
144
145    @Override
146    public PublishedDocument wrapToPublishedDocument(DocumentModel documentModel) {
147        return new ExternalCorePublishedDocument(documentModel);
148    }
149
150}