001/* 002 * Copyright 2016 Anyware Services 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 */ 016package org.ametys.plugins.workspaces.documents; 017 018import java.util.HashMap; 019import java.util.Map; 020import java.util.Set; 021 022import org.apache.avalon.framework.context.Context; 023import org.apache.avalon.framework.context.ContextException; 024import org.apache.cocoon.components.ContextHelper; 025import org.apache.cocoon.environment.Request; 026import org.apache.commons.lang.IllegalClassException; 027 028import org.ametys.cms.transformation.xslt.ResolveURIComponent; 029import org.ametys.core.right.RightManager.RightResult; 030import org.ametys.core.ui.Callable; 031import org.ametys.core.user.UserIdentity; 032import org.ametys.plugins.explorer.ExplorerNode; 033import org.ametys.plugins.explorer.resources.ModifiableResourceCollection; 034import org.ametys.plugins.explorer.resources.jcr.JCRResourcesCollectionFactory; 035import org.ametys.plugins.repository.AmetysObject; 036import org.ametys.plugins.repository.AmetysObjectIterable; 037import org.ametys.plugins.repository.AmetysRepositoryException; 038import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 039import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 040import org.ametys.plugins.workspaces.AbstractWorkspaceModule; 041import org.ametys.plugins.workspaces.project.objects.Project; 042import org.ametys.runtime.i18n.I18nizableText; 043import org.ametys.web.repository.page.ModifiablePage; 044import org.ametys.web.repository.page.ModifiableZone; 045import org.ametys.web.repository.page.ModifiableZoneItem; 046import org.ametys.web.repository.page.Page; 047import org.ametys.web.repository.page.ZoneItem.ZoneType; 048 049import com.google.common.collect.ImmutableSet; 050 051/** 052 * Helper component for managing documents 053 */ 054public class DocumentWorkspaceModule extends AbstractWorkspaceModule 055{ 056 /** The id of document module */ 057 public static final String DODUMENT_MODULE_ID = DocumentWorkspaceModule.class.getName(); 058 059 /** Workspaces documents node name */ 060 public static final String WORKSPACES_DOCUMENTS_NODE_NAME = "documents"; 061 062 /** Tag on the main page holding the document module */ 063 private static final String __DOCUMENT_MODULE_TAG = "WORKSPACES_MODULE_DOCUMENT"; 064 065 /** Module i18n title key */ 066 private static final String __MODULE_TITLE_KEY = "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_DOCUMENT_LABEL"; 067 068 @Override 069 public void contextualize(Context context) throws ContextException 070 { 071 _context = context; 072 } 073 074 @Override 075 public String getId() 076 { 077 return DODUMENT_MODULE_ID; 078 } 079 080 @Override 081 public I18nizableText getModuleTitle() 082 { 083 return new I18nizableText("plugin." + _pluginName, __MODULE_TITLE_KEY); 084 } 085 086 @Override 087 protected String getModulePageName() 088 { 089 return "documents"; 090 } 091 092 @Override 093 protected I18nizableText getModulePageTitle() 094 { 095 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_WORKSPACE_PAGE_DOCUMENTS_TITLE"); 096 } 097 098 @Override 099 protected String getModuleTagName() 100 { 101 return __DOCUMENT_MODULE_TAG; 102 } 103 104 @Override 105 protected void initializeModulePage(ModifiablePage documentPage) 106 { 107 ModifiableZone defaultZone = documentPage.createZone("default"); 108 109 String serviceId = "org.ametys.plugins.workspaces.module.Document"; 110 ModifiableZoneItem defaultZoneItem = defaultZone.addZoneItem(); 111 defaultZoneItem.setType(ZoneType.SERVICE); 112 defaultZoneItem.setServiceId(serviceId); 113 114 ModifiableCompositeMetadata serviceMetadata = defaultZoneItem.getServiceParameters(); 115 serviceMetadata.setMetadata("xslt", _getDefaultXslt(serviceId)); 116 } 117 118 /** 119 * Get the URI of a folder in project'site 120 * @param project The project 121 * @param collectionId The id of collection 122 * @param language The sitemap language 123 * @return The thread uri 124 */ 125 public String getFolderUri(Project project, String collectionId, String language) 126 { 127 AmetysObjectIterable<Page> pages = getModulePages(project, language); 128 129 if (pages.getSize() > 0) 130 { 131 Page page = pages.iterator().next(); 132 133 StringBuilder sb = new StringBuilder(); 134 sb.append(ResolveURIComponent.resolve("page", page.getId())); 135 sb.append("#").append(collectionId); 136 137 return sb.toString(); 138 } 139 140 return null; 141 } 142 143 /** 144 * Retrieves the set of general rights used in the document module for the current user 145 * @return The map of right data. Keys are the rights id, and values indicates whether the current user has the right or not. 146 */ 147 @Callable 148 public Map<String, Object> getModuleBaseRights() 149 { 150 Request request = ContextHelper.getRequest(_context); 151 152 String projectName = (String) request.getAttribute("projectName"); 153 Project project = _projectManager.getProject(projectName); 154 155 ModifiableResourceCollection documentRoot = getModuleRoot(project, false); 156 157 Map<String, Object> rightsData = new HashMap<>(); 158 UserIdentity user = _currentUserProvider.getUser(); 159 160 // Add file / folder 161 rightsData.put("add-file", _rightManager.hasRight(user, "Plugin_Explorer_File_Add", documentRoot) == RightResult.RIGHT_ALLOW); 162 rightsData.put("add-folder", _rightManager.hasRight(user, "Plugin_Explorer_Folder_Add", documentRoot) == RightResult.RIGHT_ALLOW); 163 rightsData.put("add-cmis-folder", _rightManager.hasRight(user, "Plugin_Explorer_CMIS_Add", documentRoot) == RightResult.RIGHT_ALLOW); 164 165 // Tags 166 rightsData.put("add-tag", _projectRightHelper.hasRight("Plugins_Workspaces_Rights_Project_Add_Tag", project)); 167 rightsData.put("remove-tag", _projectRightHelper.hasRight("Plugins_Workspaces_Rights_Project_Delete_Tag", project)); 168 169 return rightsData; 170 } 171 172 @Override 173 public ModifiableResourceCollection getModuleRoot(Project project, boolean create) 174 { 175 try 176 { 177 ExplorerNode projectRootNode = project.getExplorerRootNode(); 178 179 if (projectRootNode instanceof ModifiableResourceCollection) 180 { 181 ModifiableResourceCollection projectRootNodeRc = (ModifiableResourceCollection) projectRootNode; 182 return _getAmetysObject(projectRootNodeRc, WORKSPACES_DOCUMENTS_NODE_NAME, JCRResourcesCollectionFactory.RESOURCESCOLLECTION_NODETYPE, create); 183 } 184 else 185 { 186 throw new IllegalClassException(ModifiableResourceCollection.class, projectRootNode.getClass()); 187 } 188 } 189 catch (AmetysRepositoryException e) 190 { 191 throw new AmetysRepositoryException("Error getting the documents root node.", e); 192 } 193 } 194 195 196 /** 197 * Utility method to get or create an ametys object 198 * @param <A> A sub class of AmetysObject 199 * @param parent The parent object 200 * @param name The ametys object name 201 * @param type The ametys object type 202 * @param create True to create the object if it does not exist 203 * @return ametys object 204 * @throws AmetysRepositoryException if an repository error occurs 205 */ 206 protected <A extends AmetysObject> A _getAmetysObject(ModifiableTraversableAmetysObject parent, String name, String type, boolean create) throws AmetysRepositoryException 207 { 208 A object = null; 209 210 if (parent.hasChild(name)) 211 { 212 object = parent.getChild(name); 213 } 214 else if (create) 215 { 216 object = parent.createChild(name, type); 217 parent.saveChanges(); 218 } 219 220 return object; 221 } 222 223 @Override 224 public Set<String> getAllowedEventTypes() 225 { 226 return ImmutableSet.of("resource.created", "resource.updated", "resource.renamed"); 227 } 228}