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}