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