001/* 002 * (C) Copyright 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 * Thierry Delprat 018 */ 019package org.nuxeo.ecm.platform.publisher.impl.finder; 020 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.HashSet; 024import java.util.List; 025import java.util.Set; 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.DocumentNotFoundException; 033import org.nuxeo.ecm.core.api.DocumentRef; 034import org.nuxeo.ecm.core.api.Filter; 035import org.nuxeo.ecm.core.api.IdRef; 036import org.nuxeo.ecm.core.api.LifeCycleConstants; 037import org.nuxeo.ecm.core.api.PathRef; 038import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; 039import org.nuxeo.ecm.core.api.impl.CompoundFilter; 040import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl; 041import org.nuxeo.ecm.core.api.impl.FacetFilter; 042import org.nuxeo.ecm.core.api.impl.LifeCycleFilter; 043import org.nuxeo.ecm.core.api.security.SecurityConstants; 044import org.nuxeo.ecm.core.schema.FacetNames; 045import org.nuxeo.ecm.core.schema.SchemaManager; 046import org.nuxeo.ecm.platform.publisher.helper.RootSectionFinder; 047import org.nuxeo.runtime.api.Framework; 048 049public abstract class AbstractRootSectionsFinder extends UnrestrictedSessionRunner implements RootSectionFinder { 050 051 public static final String SCHEMA_PUBLISHING = "publishing"; 052 053 public static final String SECTIONS_PROPERTY_NAME = "publish:sections"; 054 055 protected static Set<String> sectionRootTypes; 056 057 protected static Set<String> sectionTypes; 058 059 protected CoreSession userSession; 060 061 protected List<String> unrestrictedSectionRootFromWorkspaceConfig; 062 063 protected List<String> unrestrictedDefaultSectionRoot; 064 065 protected DocumentModelList accessibleSectionRoots; 066 067 protected DocumentModel currentDocument; 068 069 protected static final Log log = LogFactory.getLog(AbstractRootSectionsFinder.class); 070 071 protected abstract void computeUserSectionRoots(DocumentModel currentDoc); 072 073 protected abstract String buildQuery(String path); 074 075 protected abstract void computeUnrestrictedRoots(CoreSession session); 076 077 public AbstractRootSectionsFinder(CoreSession userSession) { 078 super(userSession); 079 this.userSession = userSession; 080 } 081 082 @Override 083 public void reset() { 084 this.currentDocument = null; 085 } 086 087 @Override 088 public DocumentModelList getAccessibleSectionRoots(DocumentModel currentDoc) { 089 if ((currentDocument == null) || (!currentDocument.getRef().equals(currentDoc.getRef()))) { 090 computeUserSectionRoots(currentDoc); 091 } 092 return accessibleSectionRoots; 093 } 094 095 @Override 096 public DocumentModelList getSectionRootsForWorkspace(DocumentModel currentDoc, boolean addDefaultSectionRoots) 097 { 098 if ((currentDocument == null) || (!currentDocument.getRef().equals(currentDoc.getRef()))) { 099 computeUserSectionRoots(currentDoc); 100 } 101 102 if (unrestrictedDefaultSectionRoot.isEmpty() && addDefaultSectionRoots) { 103 DocumentModelList defaultSectionRoots = getDefaultSectionRoots(session); 104 unrestrictedDefaultSectionRoot = new ArrayList<String>(); 105 for (DocumentModel root : defaultSectionRoots) { 106 unrestrictedDefaultSectionRoot.add(root.getPathAsString()); 107 } 108 } 109 110 return getFiltredSectionRoots(unrestrictedSectionRootFromWorkspaceConfig, true); 111 } 112 113 @Override 114 public DocumentModelList getSectionRootsForWorkspace(DocumentModel currentDoc) { 115 return getSectionRootsForWorkspace(currentDoc, false); 116 } 117 118 @Override 119 public DocumentModelList getDefaultSectionRoots(boolean onlyHeads, boolean addDefaultSectionRoots) 120 { 121 if (unrestrictedDefaultSectionRoot == null) { 122 computeUserSectionRoots(null); 123 } 124 125 if (unrestrictedDefaultSectionRoot.isEmpty() && addDefaultSectionRoots) { 126 DocumentModelList defaultSectionRoots = getDefaultSectionRoots(session); 127 unrestrictedDefaultSectionRoot = new ArrayList<String>(); 128 for (DocumentModel root : defaultSectionRoots) { 129 unrestrictedDefaultSectionRoot.add(root.getPathAsString()); 130 } 131 } 132 133 return getFiltredSectionRoots(unrestrictedDefaultSectionRoot, onlyHeads); 134 } 135 136 @Override 137 public DocumentModelList getDefaultSectionRoots(boolean onlyHeads) { 138 return getDefaultSectionRoots(onlyHeads, false); 139 } 140 141 protected DocumentModelList getFiltredSectionRoots(List<String> rootPaths, boolean onlyHeads) 142 { 143 List<DocumentRef> filtredDocRef = new ArrayList<DocumentRef>(); 144 List<DocumentRef> trashedDocRef = new ArrayList<DocumentRef>(); 145 146 for (String rootPath : rootPaths) { 147 DocumentRef rootRef = new PathRef(rootPath); 148 if (userSession.hasPermission(rootRef, SecurityConstants.READ)) { 149 filtredDocRef.add(rootRef); 150 } else { 151 DocumentModelList accessibleSections = userSession.query(buildQuery(rootPath)); 152 for (DocumentModel section : accessibleSections) { 153 if (onlyHeads 154 && ((filtredDocRef.contains(section.getParentRef())) || (trashedDocRef.contains(section.getParentRef())))) { 155 trashedDocRef.add(section.getRef()); 156 } else { 157 filtredDocRef.add(section.getRef()); 158 } 159 } 160 } 161 } 162 DocumentModelList documents = userSession.getDocuments(filtredDocRef.toArray(new DocumentRef[filtredDocRef.size()])); 163 return filterDocuments(documents); 164 } 165 166 protected DocumentModelList filterDocuments(DocumentModelList docs) { 167 DocumentModelList filteredDocuments = new DocumentModelListImpl(); 168 FacetFilter facetFilter = new FacetFilter(Arrays.asList(FacetNames.FOLDERISH), 169 Arrays.asList(FacetNames.HIDDEN_IN_NAVIGATION)); 170 LifeCycleFilter lfFilter = new LifeCycleFilter(LifeCycleConstants.DELETED_STATE, false); 171 Filter filter = new CompoundFilter(facetFilter, lfFilter); 172 for (DocumentModel doc : docs) { 173 if (filter.accept(doc)) { 174 filteredDocuments.add(doc); 175 } 176 } 177 return filteredDocuments; 178 } 179 180 protected DocumentModelList getDefaultSectionRoots(CoreSession session) { 181 // XXX replace by a query !!! 182 DocumentModelList sectionRoots = new DocumentModelListImpl(); 183 DocumentModelList domains = session.getChildren(session.getRootDocument().getRef(), "Domain"); 184 for (DocumentModel domain : domains) { 185 for (String sectionRootNameType : getSectionRootTypes()) { 186 DocumentModelList children = session.getChildren(domain.getRef(), sectionRootNameType); 187 sectionRoots.addAll(children); 188 } 189 } 190 return sectionRoots; 191 } 192 193 protected DocumentModelList getSectionRootsFromWorkspaceConfig(DocumentModel workspace, CoreSession session) 194 { 195 196 DocumentModelList selectedSections = new DocumentModelListImpl(); 197 198 if (workspace.hasSchema(SCHEMA_PUBLISHING)) { 199 String[] sectionIdsArray = (String[]) workspace.getPropertyValue(SECTIONS_PROPERTY_NAME); 200 201 List<String> sectionIdsList = new ArrayList<String>(); 202 203 if (sectionIdsArray != null && sectionIdsArray.length > 0) { 204 sectionIdsList = Arrays.asList(sectionIdsArray); 205 } 206 207 if (sectionIdsList != null) { 208 for (String currentSectionId : sectionIdsList) { 209 try { 210 DocumentModel sectionToAdd = session.getDocument(new IdRef(currentSectionId)); 211 selectedSections.add(sectionToAdd); 212 } catch (DocumentNotFoundException e) { 213 log.warn("Section with ID=" + currentSectionId + " not found for document with ID=" 214 + workspace.getId()); 215 } 216 } 217 } 218 } 219 return selectedSections; 220 } 221 222 @Override 223 public void run() { 224 computeUnrestrictedRoots(session); 225 } 226 227 protected Set<String> getSectionRootTypes() { 228 if (sectionRootTypes == null) { 229 sectionRootTypes = getTypeNamesForFacet(FacetNames.MASTER_PUBLISH_SPACE); 230 if (sectionRootTypes == null) { 231 sectionRootTypes = new HashSet<String>(); 232 } 233 } 234 return sectionRootTypes; 235 } 236 237 protected Set<String> getTypeNamesForFacet(String facetName) { 238 SchemaManager schemaManager = Framework.getService(SchemaManager.class); 239 Set<String> publishRoots = schemaManager.getDocumentTypeNamesForFacet(facetName); 240 if (publishRoots == null || publishRoots.isEmpty()) { 241 return null; 242 } 243 return publishRoots; 244 } 245 246 protected Set<String> getSectionTypes() { 247 if (sectionTypes == null) { 248 sectionTypes = getTypeNamesForFacet(FacetNames.MASTER_PUBLISH_SPACE); 249 if (sectionTypes == null) { 250 sectionTypes = new HashSet<String>(); 251 } 252 } 253 return sectionTypes; 254 } 255 256}