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