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