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