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.impl.core;
019
020import java.util.ArrayList;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.nuxeo.ecm.core.api.CoreInstance;
027import org.nuxeo.ecm.core.api.CoreSession;
028import org.nuxeo.ecm.core.api.DocumentLocation;
029import org.nuxeo.ecm.core.api.DocumentModel;
030import org.nuxeo.ecm.core.api.DocumentModelList;
031import org.nuxeo.ecm.core.api.DocumentRef;
032import org.nuxeo.ecm.core.api.NuxeoException;
033import org.nuxeo.ecm.core.api.PathRef;
034import org.nuxeo.ecm.core.api.security.SecurityConstants;
035import org.nuxeo.ecm.platform.publisher.api.AbstractBasePublicationTree;
036import org.nuxeo.ecm.platform.publisher.api.PublicationNode;
037import org.nuxeo.ecm.platform.publisher.api.PublicationTree;
038import org.nuxeo.ecm.platform.publisher.api.PublishedDocument;
039import org.nuxeo.ecm.platform.publisher.api.PublishedDocumentFactory;
040import org.nuxeo.ecm.platform.publisher.helper.PublicationRelationHelper;
041
042/**
043 * Simple implementation of a {@link PublicationTree} using the Core Sections.
044 *
045 * @author tiry
046 */
047public class SectionPublicationTree extends AbstractBasePublicationTree implements PublicationTree {
048
049    private static final long serialVersionUID = 1L;
050
051    private static final Log log = LogFactory.getLog(SectionPublicationTree.class);
052
053    public static final String CAN_ASK_FOR_PUBLISHING = "CanAskForPublishing";
054
055    protected static final String DEFAULT_ROOT_PATH = "/default-domain/sections";
056
057    protected DocumentModel treeRoot;
058
059    protected String sessionId;
060
061    @Override
062    public void initTree(String sid, CoreSession coreSession, Map<String, String> parameters,
063            PublishedDocumentFactory factory, String configName, String title) {
064        super.initTree(sid, coreSession, parameters, factory, configName, title);
065
066        DocumentRef ref = new PathRef(rootPath);
067        boolean exists = coreSession.exists(ref);
068        if (!exists) {
069            log.debug("Root section " + rootPath + " doesn't exist. Check " + "publicationTreeConfig with name "
070                    + configName);
071        }
072        if (exists && coreSession.hasPermission(ref, SecurityConstants.READ)) {
073            treeRoot = coreSession.getDocument(new PathRef(rootPath));
074            rootNode = new CoreFolderPublicationNode(treeRoot, getConfigName(), sid, factory);
075        } else {
076            rootNode = new VirtualCoreFolderPublicationNode(coreSession.getSessionId(), rootPath, getConfigName(), sid,
077                    factory);
078            sessionId = coreSession.getSessionId();
079        }
080    }
081
082    protected CoreSession getCoreSession() {
083        String coreSessionId = treeRoot == null ? sessionId : treeRoot.getSessionId();
084        return CoreInstance.getInstance().getSession(coreSessionId);
085    }
086
087    public List<PublishedDocument> getExistingPublishedDocument(DocumentLocation docLoc) {
088        List<PublishedDocument> publishedDocs = new ArrayList<PublishedDocument>();
089        DocumentModelList proxies = getCoreSession().getProxies(docLoc.getDocRef(), null);
090        for (DocumentModel proxy : proxies) {
091            if (proxy.getPathAsString().startsWith(rootPath)) {
092                publishedDocs.add(factory.wrapDocumentModel(proxy));
093            }
094        }
095        return publishedDocs;
096    }
097
098    @Override
099    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode) {
100        SimpleCorePublishedDocument publishedDocument = (SimpleCorePublishedDocument) super.publish(doc, targetNode);
101        PublicationRelationHelper.addPublicationRelation(publishedDocument.getProxy(), this);
102        return publishedDocument;
103    }
104
105    @Override
106    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode, Map<String, String> params)
107            {
108        SimpleCorePublishedDocument publishedDocument = (SimpleCorePublishedDocument) super.publish(doc, targetNode,
109                params);
110        PublicationRelationHelper.addPublicationRelation(publishedDocument.getProxy(), this);
111        return publishedDocument;
112    }
113
114    public void unpublish(DocumentModel doc, PublicationNode targetNode) {
115        List<PublishedDocument> publishedDocs = getPublishedDocumentInNode(targetNode);
116        for (PublishedDocument pubDoc : publishedDocs) {
117            if (pubDoc.getSourceDocumentRef().equals(doc.getRef())) {
118                unpublish(pubDoc);
119            }
120        }
121    }
122
123    public void unpublish(PublishedDocument publishedDocument) {
124        if (!accept(publishedDocument)) {
125            return;
126        }
127        DocumentModel proxy = ((SimpleCorePublishedDocument) publishedDocument).getProxy();
128        PublicationRelationHelper.removePublicationRelation(proxy);
129        getCoreSession().removeDocument(proxy.getRef());
130        getCoreSession().save();
131    }
132
133    public PublicationNode getNodeByPath(String path) {
134        DocumentRef docRef = new PathRef(path);
135        if (coreSession.hasPermission(docRef, SecurityConstants.READ)) {
136            return new CoreFolderPublicationNode(coreSession.getDocument(new PathRef(path)), getConfigName(),
137                    getSessionId(), factory);
138        } else {
139            return new VirtualCoreFolderPublicationNode(coreSession.getSessionId(), path, getConfigName(), sid, factory);
140        }
141
142    }
143
144    public void release() {
145        // TODO Auto-generated method stub
146    }
147
148    @Override
149    protected String getDefaultRootPath() {
150        return DEFAULT_ROOT_PATH;
151    }
152
153    @Override
154    protected PublishedDocumentFactory getDefaultFactory() {
155        return new CoreProxyFactory();
156    }
157
158    @Override
159    public boolean canPublishTo(PublicationNode publicationNode) {
160        if (publicationNode == null || publicationNode.getParent() == null) {
161            // we can't publish in the root node
162            return false;
163        }
164        DocumentRef docRef = new PathRef(publicationNode.getPath());
165        return coreSession.hasPermission(docRef, CAN_ASK_FOR_PUBLISHING);
166    }
167
168    @Override
169    public boolean canUnpublish(PublishedDocument publishedDocument) {
170        if (!accept(publishedDocument)) {
171            return false;
172        }
173        DocumentRef docRef = new PathRef(publishedDocument.getParentPath());
174        return coreSession.hasPermission(docRef, SecurityConstants.WRITE);
175    }
176
177    @Override
178    public PublishedDocument wrapToPublishedDocument(DocumentModel documentModel) {
179        return factory.wrapDocumentModel(documentModel);
180    }
181
182    @Override
183    public boolean isPublicationNode(DocumentModel documentModel) {
184        return documentModel.getPathAsString().startsWith(rootPath);
185    }
186
187    @Override
188    public PublicationNode wrapToPublicationNode(DocumentModel documentModel) {
189        if (!isPublicationNode(documentModel)) {
190            throw new NuxeoException("Document " + documentModel.getPathAsString()
191                    + " is not a valid publication node.");
192        }
193        return new CoreFolderPublicationNode(documentModel, getConfigName(), sid, factory);
194    }
195
196    @Override
197    protected boolean accept(PublishedDocument publishedDocument) {
198        return publishedDocument instanceof SimpleCorePublishedDocument;
199    }
200
201}