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.CoreInstance;
029import org.nuxeo.ecm.core.api.CoreSession;
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;
043
044/**
045 * Simple implementation of a {@link PublicationTree} using the Core Sections.
046 *
047 * @author tiry
048 */
049public class SectionPublicationTree extends AbstractBasePublicationTree implements PublicationTree {
050
051    private static final long serialVersionUID = 1L;
052
053    private static final Log log = LogFactory.getLog(SectionPublicationTree.class);
054
055    public static final String CAN_ASK_FOR_PUBLISHING = "CanAskForPublishing";
056
057    protected static final String DEFAULT_ROOT_PATH = "/default-domain/sections";
058
059    protected DocumentModel treeRoot;
060
061    protected String sessionId;
062
063    @Override
064    public void initTree(String sid, CoreSession coreSession, Map<String, String> parameters,
065            PublishedDocumentFactory factory, String configName, String title) {
066        super.initTree(sid, coreSession, parameters, factory, configName, title);
067
068        DocumentRef ref = new PathRef(rootPath);
069        boolean exists = coreSession.exists(ref);
070        if (!exists) {
071            log.debug("Root section " + rootPath + " doesn't exist. Check " + "publicationTreeConfig with name "
072                    + configName);
073        }
074        if (exists && coreSession.hasPermission(ref, SecurityConstants.READ)) {
075            treeRoot = coreSession.getDocument(new PathRef(rootPath));
076            rootNode = new CoreFolderPublicationNode(treeRoot, getConfigName(), sid, factory);
077        } else {
078            rootNode = new VirtualCoreFolderPublicationNode(coreSession.getSessionId(), rootPath, getConfigName(), sid,
079                    factory);
080            sessionId = coreSession.getSessionId();
081        }
082    }
083
084    protected CoreSession getCoreSession() {
085        String coreSessionId = treeRoot == null ? sessionId : treeRoot.getSessionId();
086        return CoreInstance.getInstance().getSession(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)), getConfigName(),
139                    getSessionId(), factory);
140        } else {
141            return new VirtualCoreFolderPublicationNode(coreSession.getSessionId(), path, getConfigName(), sid, factory);
142        }
143
144    }
145
146    public void release() {
147        // TODO Auto-generated method stub
148    }
149
150    @Override
151    protected String getDefaultRootPath() {
152        return DEFAULT_ROOT_PATH;
153    }
154
155    @Override
156    protected PublishedDocumentFactory getDefaultFactory() {
157        return new CoreProxyFactory();
158    }
159
160    @Override
161    public boolean canPublishTo(PublicationNode publicationNode) {
162        if (publicationNode == null || publicationNode.getParent() == null) {
163            // we can't publish in the root node
164            return false;
165        }
166        DocumentRef docRef = new PathRef(publicationNode.getPath());
167        return coreSession.hasPermission(docRef, CAN_ASK_FOR_PUBLISHING);
168    }
169
170    @Override
171    public boolean canUnpublish(PublishedDocument publishedDocument) {
172        if (!accept(publishedDocument)) {
173            return false;
174        }
175        DocumentRef docRef = new PathRef(publishedDocument.getParentPath());
176        return coreSession.hasPermission(docRef, SecurityConstants.WRITE);
177    }
178
179    @Override
180    public PublishedDocument wrapToPublishedDocument(DocumentModel documentModel) {
181        return factory.wrapDocumentModel(documentModel);
182    }
183
184    @Override
185    public boolean isPublicationNode(DocumentModel documentModel) {
186        return documentModel.getPathAsString().startsWith(rootPath);
187    }
188
189    @Override
190    public PublicationNode wrapToPublicationNode(DocumentModel documentModel) {
191        if (!isPublicationNode(documentModel)) {
192            throw new NuxeoException("Document " + documentModel.getPathAsString()
193                    + " is not a valid publication node.");
194        }
195        return new CoreFolderPublicationNode(documentModel, getConfigName(), sid, factory);
196    }
197
198    @Override
199    protected boolean accept(PublishedDocument publishedDocument) {
200        return publishedDocument instanceof SimpleCorePublishedDocument;
201    }
202
203}