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