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.Arrays;
022import java.util.Collections;
023import java.util.List;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.nuxeo.ecm.core.api.CoreSession;
028import org.nuxeo.ecm.core.api.DocumentModel;
029import org.nuxeo.ecm.core.api.DocumentModelList;
030import org.nuxeo.ecm.core.api.DocumentRef;
031import org.nuxeo.ecm.core.api.Filter;
032import org.nuxeo.ecm.core.api.LifeCycleConstants;
033import org.nuxeo.ecm.core.api.impl.CompoundFilter;
034import org.nuxeo.ecm.core.api.impl.FacetFilter;
035import org.nuxeo.ecm.core.api.impl.LifeCycleFilter;
036import org.nuxeo.ecm.core.api.security.SecurityConstants;
037import org.nuxeo.ecm.core.api.tree.DefaultDocumentTreeSorter;
038import org.nuxeo.ecm.core.schema.FacetNames;
039import org.nuxeo.ecm.platform.publisher.api.AbstractPublicationNode;
040import org.nuxeo.ecm.platform.publisher.api.PublicationNode;
041import org.nuxeo.ecm.platform.publisher.api.PublicationTree;
042import org.nuxeo.ecm.platform.publisher.api.PublishedDocument;
043import org.nuxeo.ecm.platform.publisher.api.PublishedDocumentFactory;
044
045/**
046 * Implementation of the {@link PublicationNode} for Simple Core Folders.
047 *
048 * @author tiry
049 */
050public class CoreFolderPublicationNode extends AbstractPublicationNode implements PublicationNode {
051
052    private static final long serialVersionUID = 1L;
053
054    private static final Log log = LogFactory.getLog(CoreFolderPublicationNode.class);
055
056    private static final String DEFAULT_SORT_PROP_NAME = "dc:title";
057
058    protected DocumentModel folder;
059
060    protected PublicationNode parent;
061
062    protected String treeConfigName;
063
064    protected PublishedDocumentFactory factory;
065
066    protected String sid;
067
068    public CoreFolderPublicationNode(DocumentModel doc, PublicationTree tree, PublishedDocumentFactory factory)
069            {
070        this.folder = doc;
071        this.treeConfigName = tree.getConfigName();
072        this.factory = factory;
073        this.sid = tree.getSessionId();
074    }
075
076    public CoreFolderPublicationNode(DocumentModel doc, PublicationTree tree, PublicationNode parent,
077            PublishedDocumentFactory factory) {
078        this.folder = doc;
079        this.treeConfigName = tree.getConfigName();
080        this.parent = parent;
081        this.factory = factory;
082        this.sid = tree.getSessionId();
083    }
084
085    public CoreFolderPublicationNode(DocumentModel doc, String treeConfigName, String sid, PublicationNode parent,
086            PublishedDocumentFactory factory) {
087        this.folder = doc;
088        this.treeConfigName = treeConfigName;
089        this.parent = parent;
090        this.factory = factory;
091        this.sid = sid;
092    }
093
094    public CoreFolderPublicationNode(DocumentModel doc, String treeConfigName, String sid,
095            PublishedDocumentFactory factory) {
096        this.folder = doc;
097        this.treeConfigName = treeConfigName;
098        this.factory = factory;
099        this.sid = sid;
100    }
101
102    protected CoreSession getCoreSession() {
103        return folder.getCoreSession();
104    }
105
106    protected String buildChildrenWhereClause(boolean queryDocuments) {
107        String clause = String.format("ecm:parentId = '%s' AND ecm:currentLifeCycleState != '%s'", folder.getId(),
108                LifeCycleConstants.DELETED_STATE);
109        if (queryDocuments) {
110            clause += String.format(" AND ecm:mixinType NOT IN ('%s', '%s')", FacetNames.PUBLISH_SPACE,
111                    FacetNames.HIDDEN_IN_NAVIGATION);
112        } else {
113            clause += String.format("AND ecm:mixinType IN ('%s') AND ecm:mixinType NOT IN ('%s')",
114                    FacetNames.PUBLISH_SPACE, FacetNames.HIDDEN_IN_NAVIGATION);
115        }
116        return clause;
117    }
118
119    public List<PublishedDocument> getChildrenDocuments() {
120        DocumentModelList children = getSortedChildren(true);
121        List<PublishedDocument> childrenDocs = new ArrayList<PublishedDocument>();
122        for (DocumentModel child : children) {
123            childrenDocs.add(factory.wrapDocumentModel(child));
124        }
125        return childrenDocs;
126    }
127
128    public List<PublicationNode> getChildrenNodes() {
129        DocumentModelList children = getSortedChildren(false);
130
131        List<PublicationNode> childrenNodes = new ArrayList<PublicationNode>();
132        for (DocumentModel child : children) {
133            childrenNodes.add(new CoreFolderPublicationNode(child, treeConfigName, sid, this, factory));
134        }
135        return childrenNodes;
136    }
137
138    protected DocumentModelList getOrderedChildren() {
139        return getCoreSession().getChildren(folder.getRef(), null, null, computeGetChildrenFilter(), null);
140    }
141
142    protected Filter computeGetChildrenFilter() {
143        FacetFilter facetFilter = new FacetFilter(Arrays.asList(FacetNames.FOLDERISH),
144                Arrays.asList(FacetNames.HIDDEN_IN_NAVIGATION));
145        LifeCycleFilter lfFilter = new LifeCycleFilter(LifeCycleConstants.DELETED_STATE, false);
146        return new CompoundFilter(facetFilter, lfFilter);
147    }
148
149    protected DocumentModelList getSortedChildren(boolean queryDocuments) {
150        String whereClause = buildChildrenWhereClause(queryDocuments);
151        DocumentModelList children = getCoreSession().query("SELECT * FROM Document WHERE " + whereClause);
152        if (!folder.hasFacet(FacetNames.ORDERABLE)) {
153            DefaultDocumentTreeSorter sorter = new DefaultDocumentTreeSorter();
154            sorter.setSortPropertyPath(DEFAULT_SORT_PROP_NAME);
155            Collections.sort(children, sorter);
156        }
157        return children;
158    }
159
160    public String getTitle() {
161        return folder.getTitle();
162    }
163
164    public String getName() {
165        return folder.getName();
166    }
167
168    public PublicationNode getParent() {
169        if (parent == null) {
170            DocumentRef docRef = folder.getParentRef();
171            if (getCoreSession().hasPermission(docRef, SecurityConstants.READ)) {
172                parent = new CoreFolderPublicationNode(getCoreSession().getDocument(folder.getParentRef()),
173                        treeConfigName, sid, factory);
174            } else {
175                parent = new VirtualCoreFolderPublicationNode(getCoreSession().getSessionId(), docRef.toString(),
176                        treeConfigName, sid, factory);
177            }
178        }
179        return parent;
180    }
181
182    public String getPath() {
183        return folder.getPathAsString();
184    }
185
186    @Override
187    public String getTreeConfigName() {
188        return treeConfigName;
189    }
190
191    public DocumentRef getTargetDocumentRef() {
192        return folder.getRef();
193    }
194
195    public DocumentModel getTargetDocumentModel() {
196        return folder;
197    }
198
199    public String getSessionId() {
200        return sid;
201    }
202
203}