001/* 002 * Copyright 2015 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.explorer.calendars.clientside; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.LinkedList; 023import java.util.List; 024import java.util.Map; 025import java.util.Set; 026 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.commons.lang3.BooleanUtils; 030 031import org.ametys.core.ui.Callable; 032import org.ametys.core.ui.StaticClientSideElement; 033import org.ametys.plugins.explorer.calendars.Calendar; 034import org.ametys.plugins.explorer.calendars.CalendarEvent; 035import org.ametys.plugins.explorer.workflow.AbstractExplorerNodeWorkflowComponent; 036import org.ametys.plugins.repository.AmetysObject; 037import org.ametys.plugins.repository.AmetysObjectResolver; 038import org.ametys.plugins.workflow.support.WorkflowHelper; 039import org.ametys.plugins.workflow.support.WorkflowProvider; 040import org.ametys.runtime.i18n.I18nizableText; 041 042import com.opensymphony.workflow.Workflow; 043import com.opensymphony.workflow.loader.ActionDescriptor; 044import com.opensymphony.workflow.loader.StepDescriptor; 045import com.opensymphony.workflow.loader.WorkflowDescriptor; 046import com.opensymphony.workflow.spi.Step; 047 048/** 049 * Ribbon tab client side element for calendars 050 */ 051public class CalendarsTabClientSideElement extends StaticClientSideElement 052{ 053 /** The workflow provider */ 054 protected WorkflowProvider _workflowProvider; 055 056 /** The workflow helper */ 057 protected WorkflowHelper _workflowHelper; 058 059 /** The ametys resolver */ 060 protected AmetysObjectResolver _resolver; 061 062 @Override 063 public void service(ServiceManager serviceManager) throws ServiceException 064 { 065 super.service(serviceManager); 066 _workflowProvider = (WorkflowProvider) serviceManager.lookup(WorkflowProvider.ROLE); 067 _workflowHelper = (WorkflowHelper) serviceManager.lookup(WorkflowHelper.ROLE); 068 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 069 } 070 071 @Override 072 public List<Script> getScripts(boolean ignoreRights, Map<String, Object> contextParameters) 073 { 074 List<Script> scripts = super.getScripts(ignoreRights, contextParameters); 075 if (scripts.size() > 0) 076 { 077 scripts.get(0).getParameters().put("workflows", getWorkflowsInfo()); 078 } 079 return scripts; 080 } 081 082 /** 083 * Get info about each existing workflow. 084 * @return a list of map containing workflow info. For each entry, the key 085 * is the workflow name and the value is a map containing the 086 * necessary workflow data 087 */ 088 public Map<String, Object> getWorkflowsInfo() 089 { 090 Map<String, Object> workflowsMap = new HashMap<>(); 091 092 for (String workflowName : _workflowHelper.getWorkflowNames()) 093 { 094 Map<String, Object> workflowEntry = new HashMap<>(); 095 workflowsMap.put(workflowName, workflowEntry); 096 097 WorkflowDescriptor workflowDescriptor = _workflowHelper.getWorkflowDescriptor(workflowName); 098 if (workflowDescriptor != null) 099 { 100 _addWorkflowInfo(workflowEntry, workflowDescriptor); 101 _addStepsInfo(workflowEntry, workflowDescriptor); 102 _addActionsInfo(workflowEntry, workflowDescriptor); 103 } 104 } 105 106 return workflowsMap; 107 } 108 109 /** 110 * Add workflow info to the result map 111 * @param result The result map to populate 112 * @param workflowDescriptor the workflow descriptor 113 */ 114 protected void _addWorkflowInfo(Map<String, Object> result, WorkflowDescriptor workflowDescriptor) 115 { 116 result.put("name", workflowDescriptor.getName()); 117 } 118 119 /** 120 * Add steps info to the result map 121 * @param result The result map to populate 122 * @param workflowDescriptor the workflow descriptor 123 */ 124 protected void _addStepsInfo(Map<String, Object> result, WorkflowDescriptor workflowDescriptor) 125 { 126 Map<String, Object> stepMap = new HashMap<>(); 127 result.put("steps", stepMap); 128 129 List<StepDescriptor> steps = workflowDescriptor.getSteps(); 130 for (StepDescriptor step : steps) 131 { 132 _addStepInfo(stepMap, workflowDescriptor, step); 133 } 134 } 135 136 /** 137 * Add step info to the map of steps 138 * @param stepMap The step map to populate 139 * @param workflowDescriptor the workflow descriptor 140 * @param step the step descriptor 141 */ 142 protected void _addStepInfo(Map<String, Object> stepMap, WorkflowDescriptor workflowDescriptor, StepDescriptor step) 143 { 144 int stepId = step.getId(); 145 String stepName = step.getName(); 146 147 Map<String, Object> stepInfo = new HashMap<>(); 148 stepMap.put(String.valueOf(stepId), stepInfo); 149 150 stepInfo.put("id", stepId); 151 stepInfo.put("name", stepName); 152 153 stepInfo.put("label", new I18nizableText("application", stepName)); 154 stepInfo.put("description", new I18nizableText("application", stepName + "_DESCRIPTION")); 155 156 // Default icons 157 String[] icons = new String[]{"-small", "-medium", "-large"}; 158 for (String icon : icons) 159 { 160 I18nizableText i18nStepName = new I18nizableText("application", stepName); 161 if ("application".equals(i18nStepName.getCatalogue())) 162 { 163 stepInfo.put("icon" + icon, new I18nizableText("/plugins/explorer/resources_workflow/" + i18nStepName.getKey() + icon + ".png")); 164 } 165 else 166 { 167 String pluginName = i18nStepName.getCatalogue().substring("plugin.".length()); 168 stepInfo.put("icon" + icon, new I18nizableText("/plugins/" + pluginName + "/resources/img/workflow/" + i18nStepName.getKey() + icon + ".png")); 169 } 170 } 171 172 List<Integer> actionsId = new LinkedList<>(); 173 stepInfo.put("actions", actionsId); 174 175 for (int actionId : _workflowHelper.getAllActionsFromStep(workflowDescriptor.getName(), stepId)) 176 { 177 actionsId.add(actionId); 178 } 179 } 180 181 /** 182 * Add actions info to the result map 183 * @param result The result map to populate 184 * @param workflowDescriptor the workflow descriptor 185 */ 186 protected void _addActionsInfo(Map<String, Object> result, WorkflowDescriptor workflowDescriptor) 187 { 188 Map<String, Object> actionMap = new HashMap<>(); 189 result.put("actions", actionMap); 190 191 int[] allActions = _workflowHelper.getAllActions(workflowDescriptor.getName()); 192 for (int actionId : allActions) 193 { 194 ActionDescriptor action = workflowDescriptor.getAction(actionId); 195 _addActionInfo(actionMap, workflowDescriptor, action); 196 } 197 } 198 199 /** 200 * Add action info to the map of actions 201 * @param actionMap The action map to populate 202 * @param workflowDescriptor the workflow descriptor 203 * @param action the action descriptor 204 */ 205 protected void _addActionInfo(Map<String, Object> actionMap, WorkflowDescriptor workflowDescriptor, ActionDescriptor action) 206 { 207 int actionId = action.getId(); 208 String actionName = action.getName(); 209 210 Map<String, Object> actionInfo = new HashMap<>(); 211 actionMap.put(String.valueOf(actionId), actionInfo); 212 213 actionInfo.put("id", actionId); 214 actionInfo.put("name", actionName); 215 216 actionInfo.put("label", new I18nizableText("application", actionName)); 217 actionInfo.put("description", new I18nizableText("application", actionName + "_DESCRIPTION")); 218 219 actionInfo.put("internal", BooleanUtils.toBoolean((String) action.getMetaAttributes().get("internal"))); 220 } 221 222 /** 223 * Retrieves the child workflow names for a given calendar 224 * @param calendarId The calendar identifier 225 * @return The child workflow names 226 */ 227 @Callable 228 public Set<String> getSubWorkflowNames(String calendarId) 229 { 230 Calendar calendar = _resolver.resolveById(calendarId); 231 return getSubWorkflowNames(calendar); 232 } 233 234 /** 235 * Retrieves the child workflow names for a given calendar 236 * @param calendar The calendar 237 * @return The child workflow names 238 */ 239 public Set<String> getSubWorkflowNames(Calendar calendar) 240 { 241 Set<String> workflowNames = new HashSet<>(); 242 243 for (AmetysObject ao : calendar.getChildren()) 244 { 245 if (ao instanceof Calendar) 246 { 247 Calendar child = (Calendar) ao; 248 workflowNames.add(child.getWorkflowName()); 249 workflowNames.addAll(getSubWorkflowNames(child)); 250 } 251 } 252 253 return workflowNames; 254 } 255 256 /** 257 * Get the workflow state of an event 258 * @param eventId The id of the event 259 * @param workflowName The workflow name 260 * @param workflowStepId The workflow step id 261 * @param workflowActionsIds The list of action ids 262 * @return The workflow state 263 */ 264 @Callable 265 public Map<String, Object> getWorkflowState(String eventId, String workflowName, int workflowStepId, List<Integer> workflowActionsIds) 266 { 267 Map<String, Object> results = new HashMap<>(); 268 Map<String, Object> eventMap = new HashMap<>(); 269 results.put("event", eventMap); 270 271 CalendarEvent event = _resolver.resolveById(eventId); 272 Workflow workflow = _workflowProvider.getAmetysObjectWorkflow(event); 273 274 long wId = event.getWorkflowId(); 275 if (!workflow.getWorkflowName(wId).equals(workflowName)) 276 { 277 return results; 278 } 279 280 List<Step> steps = workflow.getCurrentSteps(wId); 281 List<Integer> stepIds = new ArrayList<>(); 282 for (Step step : steps) 283 { 284 stepIds.add(step.getStepId()); 285 } 286 287 if (stepIds.contains(workflowStepId)) 288 { 289 Calendar calendar = event.getParent(); 290 291 eventMap.put("id", event.getId()); 292 eventMap.put("parentId", calendar.getId()); 293 eventMap.put("title", event.getTitle()); 294 295 String i18nKey = "PLUGINS_EXPLORER_CALENDAR_WORKFLOW_DESCRIPTION"; 296 297 List<String> workflowI18nParameters = new ArrayList<>(); 298 workflowI18nParameters.add(event.getTitle()); 299 300 eventMap.put("description", new I18nizableText("plugin.explorer", i18nKey, workflowI18nParameters)); 301 302 Map<String, Object> vars = new HashMap<>(); 303 vars.put(AbstractExplorerNodeWorkflowComponent.EXPLORERNODE_KEY, calendar); 304 305 int[] availableActions = workflow.getAvailableActions(wId, vars); 306 Arrays.sort(availableActions); 307 308 List<Integer> activeActions = new ArrayList<>(); 309 for (int actionId : workflowActionsIds) 310 { 311 if (Arrays.binarySearch(availableActions, actionId) >= 0) 312 { 313 activeActions.add(actionId); 314 } 315 } 316 eventMap.put("actions", activeActions); 317 } 318 319 return results; 320 } 321}