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 implements PublicationTree {
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(String sid, CoreSession coreSession, Map<String, String> parameters,
066            PublishedDocumentFactory factory, String configName, String title) {
067        super.initTree(sid, 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, getConfigName(), sid, factory);
078        } else {
079            rootNode = new VirtualCoreFolderPublicationNode(coreSession.getSessionId(), rootPath, getConfigName(), sid,
080                    factory);
081            sessionId = coreSession.getSessionId();
082        }
083    }
084
085    protected CoreSession getCoreSession() {
086        String coreSessionId = treeRoot == null ? sessionId : treeRoot.getSessionId();
087        return Framework.getService(CoreSessionService.class).getCoreSession(coreSessionId);
088    }
089
090    public List<PublishedDocument> getExistingPublishedDocument(DocumentLocation docLoc) {
091        List<PublishedDocument> publishedDocs = new ArrayList<PublishedDocument>();
092        DocumentModelList proxies = getCoreSession().getProxies(docLoc.getDocRef(), null);
093        for (DocumentModel proxy : proxies) {
094            if (proxy.getPathAsString().startsWith(rootPath)) {
095                publishedDocs.add(factory.wrapDocumentModel(proxy));
096            }
097        }
098        return publishedDocs;
099    }
100
101    @Override
102    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode) {
103        SimpleCorePublishedDocument publishedDocument = (SimpleCorePublishedDocument) super.publish(doc, targetNode);
104        PublicationRelationHelper.addPublicationRelation(publishedDocument.getProxy(), this);
105        return publishedDocument;
106    }
107
108    @Override
109    public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode, Map<String, String> params)
110            {
111        SimpleCorePublishedDocument publishedDocument = (SimpleCorePublishedDocument) super.publish(doc, targetNode,
112                params);
113        PublicationRelationHelper.addPublicationRelation(publishedDocument.getProxy(), this);
114        return publishedDocument;
115    }
116
117    public void unpublish(DocumentModel doc, PublicationNode targetNode) {
118        List<PublishedDocument> publishedDocs = getPublishedDocumentInNode(targetNode);
119        for (PublishedDocument pubDoc : publishedDocs) {
120            if (pubDoc.getSourceDocumentRef().equals(doc.getRef())) {
121                unpublish(pubDoc);
122            }
123        }
124    }
125
126    public void unpublish(PublishedDocument publishedDocument) {
127        if (!accept(publishedDocument)) {
128            return;
129        }
130        DocumentModel proxy = ((SimpleCorePublishedDocument) publishedDocument).getProxy();
131        PublicationRelationHelper.removePublicationRelation(proxy);
132        getCoreSession().removeDocument(proxy.getRef());
133        getCoreSession().save();
134    }
135
136    public PublicationNode getNodeByPath(String path) {
137        DocumentRef docRef = new PathRef(path);
138        if (coreSession.hasPermission(docRef, SecurityConstants.READ)) {
139            return new CoreFolderPublicationNode(coreSession.getDocument(new PathRef(path)), getConfigName(),
140                    getSessionId(), factory);
141        } else {
142            return new VirtualCoreFolderPublicationNode(coreSession.getSessionId(), path, getConfigName(), sid, factory);
143        }
144
145    }
146
147    public void release() {
148        // TODO Auto-generated method stub
149    }
150
151    @Override
152    protected String getDefaultRootPath() {
153        return DEFAULT_ROOT_PATH;
154    }
155
156    @Override
157    protected PublishedDocumentFactory getDefaultFactory() {
158        return new CoreProxyFactory();
159    }
160
161    @Override
162    public boolean canPublishTo(PublicationNode publicationNode) {
163        if (publicationNode == null || publicationNode.getParent() == null) {
164            // we can't publish in the root node
165            return false;
166        }
167        DocumentRef docRef = new PathRef(publicationNode.getPath());
168        return coreSession.hasPermission(docRef, CAN_ASK_FOR_PUBLISHING);
169    }
170
171    @Override
172    public boolean canUnpublish(PublishedDocument publishedDocument) {
173        if (!accept(publishedDocument)) {
174            return false;
175        }
176        DocumentRef docRef = new PathRef(publishedDocument.getParentPath());
177        return coreSession.hasPermission(docRef, SecurityConstants.WRITE);
178    }
179
180    @Override
181    public PublishedDocument wrapToPublishedDocument(DocumentModel documentModel) {
182        return factory.wrapDocumentModel(documentModel);
183    }
184
185    @Override
186    public boolean isPublicationNode(DocumentModel documentModel) {
187        return documentModel.getPathAsString().startsWith(rootPath);
188    }
189
190    @Override
191    public PublicationNode wrapToPublicationNode(DocumentModel documentModel) {
192        if (!isPublicationNode(documentModel)) {
193            throw new NuxeoException("Document " + documentModel.getPathAsString()
194                    + " is not a valid publication node.");
195        }
196        return new CoreFolderPublicationNode(documentModel, getConfigName(), sid, factory);
197    }
198
199    @Override
200    protected boolean accept(PublishedDocument publishedDocument) {
201        return publishedDocument instanceof SimpleCorePublishedDocument;
202    }
203
204}