001/* 002 * Copyright 2013 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.cms.clientsideelement.content; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024 025import org.apache.avalon.framework.component.Component; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029import org.apache.commons.lang.StringUtils; 030 031import org.ametys.cms.clientsideelement.SmartContentClientSideElement; 032import org.ametys.cms.content.ContentHelper; 033import org.ametys.cms.repository.Content; 034import org.ametys.cms.repository.ModifiableContent; 035import org.ametys.cms.repository.WorkflowAwareContent; 036import org.ametys.cms.workflow.AbstractContentWorkflowComponent; 037import org.ametys.core.right.RightManager; 038import org.ametys.core.right.RightManager.RightResult; 039import org.ametys.core.user.CurrentUserProvider; 040import org.ametys.core.user.User; 041import org.ametys.core.user.UserIdentity; 042import org.ametys.core.user.UserManager; 043import org.ametys.plugins.repository.lock.LockHelper; 044import org.ametys.plugins.repository.lock.LockableAmetysObject; 045import org.ametys.plugins.workflow.support.WorkflowProvider; 046import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow; 047import org.ametys.runtime.i18n.I18nizableText; 048 049import com.opensymphony.workflow.spi.Step; 050 051/** 052 * Component helper for {@link SmartContentClientSideElement} 053 * 054 */ 055public class SmartContentClientSideElementHelper implements Serviceable, Component 056{ 057 /** The Avalon Role */ 058 public static final String ROLE = SmartContentClientSideElementHelper.class.getName(); 059 060 private UserManager _userManager; 061 private WorkflowProvider _workflowProvider; 062 private CurrentUserProvider _userProvider; 063 private RightManager _rightManager; 064 private ContentHelper _contentHelper; 065 066 @Override 067 public void service(ServiceManager manager) throws ServiceException 068 { 069 _userManager = (UserManager) manager.lookup(UserManager.ROLE); 070 _workflowProvider = (WorkflowProvider) manager.lookup(WorkflowProvider.ROLE); 071 _userProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 072 _rightManager = (RightManager) manager.lookup(RightManager.ROLE); 073 _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE); 074 } 075 076 /** 077 * Determines if the workflow step is correct 078 * @param parameters The client side element 's parameters 079 * @param content the content 080 * @return true if the workflow step is incorrect 081 */ 082 public boolean isWorkflowStepCorrect(Map<String, Object> parameters, Content content) 083 { 084 WorkflowAwareContent waContent = (WorkflowAwareContent) content; 085 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent); 086 long wId = waContent.getWorkflowId(); 087 List<Step> steps = workflow.getCurrentSteps(wId); 088 089 List<Integer> stepIds = new ArrayList<>(); 090 for (Step step : steps) 091 { 092 stepIds.add(step.getStepId()); 093 } 094 095 String correctStepsAsString = parameters.get("enabled-on-workflow-step-only").toString(); 096 String[] correctStepsAsStringArray = correctStepsAsString.split(", ?"); 097 098 for (String correctStepAsString : correctStepsAsStringArray) 099 { 100 if (!StringUtils.isEmpty(correctStepAsString) && stepIds.contains(Integer.parseInt(correctStepAsString))) 101 { 102 return true; 103 } 104 } 105 106 return false; 107 } 108 109 /** 110 * Get i18n description when user can not do action because he has no right on content 111 * @param parameters The client side element 's parameters 112 * @param content The content 113 * @return The {@link I18nizableText} description 114 */ 115 public I18nizableText getNoRightDescription (Map<String, Object> parameters, Content content) 116 { 117 List<String> rightI18nParameters = new ArrayList<>(); 118 rightI18nParameters.add(_contentHelper.getTitle(content)); 119 120 I18nizableText ed = (I18nizableText) parameters.get("noright-content-description"); 121 return new I18nizableText(ed.getCatalogue(), ed.getKey(), rightI18nParameters); 122 } 123 124 /** 125 * Get i18n description when user can not do action because the content is locked 126 * @param parameters The client side element 's parameters 127 * @param content The content 128 * @return The {@link I18nizableText} description 129 */ 130 public I18nizableText getLockedDescription (Map<String, Object> parameters, Content content) 131 { 132 UserIdentity currentLockerIdentity = ((LockableAmetysObject) content).getLockOwner(); 133 User currentLocker = currentLockerIdentity != null ? _userManager.getUser(currentLockerIdentity.getPopulationId(), currentLockerIdentity.getLogin()) : null; 134 135 List<String> lockI18nParameters = new ArrayList<>(); 136 lockI18nParameters.add(_contentHelper.getTitle(content)); 137 lockI18nParameters.add(currentLocker != null ? currentLocker.getFullName() : ""); 138 lockI18nParameters.add(currentLockerIdentity != null ? currentLockerIdentity.getLogin() : "Anonymous"); 139 140 I18nizableText ed = (I18nizableText) parameters.get("locked-content-description"); 141 return new I18nizableText(ed.getCatalogue(), ed.getKey(), lockI18nParameters); 142 } 143 144 /** 145 * Get i18n description when user can not do action because there is no workflow action unvailable 146 * @param parameters The client side element 's parameters 147 * @param content The content 148 * @return The {@link I18nizableText} description 149 */ 150 public I18nizableText getWorkflowActionUnvailableDescription (Map<String, Object> parameters, Content content) 151 { 152 List<String> workflowI18nParameters = new ArrayList<>(); 153 workflowI18nParameters.add(_contentHelper.getTitle(content)); 154 155 I18nizableText ed = (I18nizableText) parameters.get("workflowaction-content-description"); 156 return new I18nizableText(ed.getCatalogue(), ed.getKey(), workflowI18nParameters); 157 } 158 159 /** 160 * Get i18n description when user can not do action because the workflow step is incorrect 161 * @param parameters The client side element 's parameters 162 * @param content The content 163 * @return The {@link I18nizableText} description 164 */ 165 public I18nizableText getIncorrectWorkflowStepDescription (Map<String, Object> parameters, Content content) 166 { 167 List<String> workflowI18nParameters = new ArrayList<>(); 168 workflowI18nParameters.add(_contentHelper.getTitle(content)); 169 170 I18nizableText ed = (I18nizableText) parameters.get("workflowstep-content-description"); 171 return new I18nizableText(ed.getCatalogue(), ed.getKey(), workflowI18nParameters); 172 } 173 174 /** 175 * Get i18n description when user can not do action because the content is not modifiable 176 * @param parameters The client side element 's parameters 177 * @param content The content 178 * @return The {@link I18nizableText} description 179 */ 180 public I18nizableText getNoModifiableDescription (Map<String, Object> parameters, Content content) 181 { 182 List<String> modifiableI18nParameters = new ArrayList<>(); 183 modifiableI18nParameters.add(_contentHelper.getTitle(content)); 184 185 I18nizableText ed = (I18nizableText) parameters.get("nomodifiable-content-description"); 186 return new I18nizableText(ed.getCatalogue(), ed.getKey(), modifiableI18nParameters); 187 } 188 189 /** 190 * Get i18n description when user can do action 191 * @param parameters The client side element 's parameters 192 * @param content The content 193 * @return The {@link I18nizableText} description 194 */ 195 public I18nizableText getAllRightDescription (Map<String, Object> parameters, Content content) 196 { 197 List<String> allrightI18nParameters = new ArrayList<>(); 198 allrightI18nParameters.add(_contentHelper.getTitle(content)); 199 200 I18nizableText ed = (I18nizableText) parameters.get("allright-content-description"); 201 return new I18nizableText(ed.getCatalogue(), ed.getKey(), allrightI18nParameters); 202 } 203 204 /** 205 * Determines if the content is locked 206 * @param content the content 207 * @return true if the content is locked 208 */ 209 public boolean isLocked(Content content) 210 { 211 if (content instanceof LockableAmetysObject) 212 { 213 LockableAmetysObject lockableContent = (LockableAmetysObject) content; 214 if (lockableContent.isLocked() && !LockHelper.isLockOwner(lockableContent, _userProvider.getUser())) 215 { 216 return true; 217 } 218 } 219 220 return false; 221 } 222 223 /** 224 * Determines if the content is modifiable 225 * @param content the content 226 * @return true if the content is modifiable 227 */ 228 public boolean isModifiable(Content content) 229 { 230 return content instanceof ModifiableContent; 231 } 232 233 /** 234 * Determines if the user has sufficient right for the given content 235 * @param rights The client side element 's rights 236 * @param content the content 237 * @return true if user has sufficient right 238 */ 239 public boolean hasRight (Map<String, String> rights, Content content) 240 { 241 if (rights.isEmpty()) 242 { 243 return true; 244 } 245 246 Set<String> rightsToCheck = rights.keySet(); 247 for (String rightToCheck : rightsToCheck) 248 { 249 if (StringUtils.isNotEmpty(rightToCheck)) 250 { 251 if (_rightManager.hasRight(_userProvider.getUser(), rightToCheck, content) == RightResult.RIGHT_ALLOW) 252 { 253 return true; 254 } 255 } 256 } 257 258 return false; 259 } 260 261 /** 262 * Determines if the workflow action is correct 263 * @param parameters The client side element 's parameters 264 * @param content the content 265 * @return true if the workflow action is incorrect 266 */ 267 public int workflowAction(Map<String, Object> parameters, Content content) 268 { 269 WorkflowAwareContent waContent = (WorkflowAwareContent) content; 270 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent); 271 long wId = waContent.getWorkflowId(); 272 273 Map<String, Object> vars = new HashMap<>(); 274 vars.put(AbstractContentWorkflowComponent.CONTENT_KEY, content); 275 int[] actionIds = workflow.getAvailableActions(wId, vars); 276 Arrays.sort(actionIds); 277 278 String correctActionsAsString = parameters.get("enabled-on-workflow-action-only").toString(); 279 String[] correctActionsAsStringArray = correctActionsAsString.split(", ?"); 280 281 int correctActionId = -1; 282 for (String correctActionAsString : correctActionsAsStringArray) 283 { 284 int actionId = Integer.parseInt(correctActionAsString); 285 if (!StringUtils.isEmpty(correctActionAsString) && Arrays.binarySearch(actionIds, actionId) >= 0) 286 { 287 correctActionId = actionId; 288 break; 289 } 290 } 291 292 return correctActionId; 293 } 294 295 /** 296 * Get the default content's parameters 297 * @param content The content 298 * @return The default parameters 299 */ 300 public Map<String, Object> getContentDefaultParameters(Content content) 301 { 302 Map<String, Object> contentParams = new HashMap<>(); 303 contentParams.put("id", content.getId()); 304 contentParams.put("title", _contentHelper.getTitle(content)); 305 306 return contentParams; 307 } 308}