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.cms.search.systemprop; 017 018import java.util.Collection; 019import java.util.Iterator; 020import java.util.LinkedHashMap; 021import java.util.List; 022import java.util.Map; 023 024import org.apache.avalon.framework.configuration.Configuration; 025import org.apache.avalon.framework.configuration.DefaultConfiguration; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028 029import org.ametys.cms.contenttype.MetadataType; 030import org.ametys.cms.repository.Content; 031import org.ametys.cms.repository.WorkflowAwareContent; 032import org.ametys.cms.search.SearchField; 033import org.ametys.cms.search.model.SystemProperty; 034import org.ametys.cms.search.query.Query; 035import org.ametys.cms.search.query.Query.Operator; 036import org.ametys.cms.search.query.WorkflowStepQuery; 037import org.ametys.cms.search.solr.field.WorkflowStepSearchField; 038import org.ametys.cms.workflow.DefaultWorkflowStepEnumerator; 039import org.ametys.plugins.workflow.support.WorkflowHelper; 040import org.ametys.plugins.workflow.support.WorkflowProvider; 041import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow; 042import org.ametys.runtime.i18n.I18nizableText; 043 044import com.opensymphony.workflow.loader.StepDescriptor; 045import com.opensymphony.workflow.loader.WorkflowDescriptor; 046import com.opensymphony.workflow.spi.Step; 047 048/** 049 * {@link SystemProperty} which represents the current workflow step ID of a content. 050 */ 051public class WorkflowStepSystemProperty extends AbstractSystemProperty 052{ 053 /** The workflow provider */ 054 protected WorkflowProvider _workflowProvider; 055 056 /** The workflow helper */ 057 protected WorkflowHelper _workflowHelper; 058 059 @Override 060 public void service(ServiceManager manager) throws ServiceException 061 { 062 super.service(manager); 063 _workflowProvider = (WorkflowProvider) manager.lookup(WorkflowProvider.ROLE); 064 _workflowHelper = (WorkflowHelper) manager.lookup(WorkflowHelper.ROLE); 065 } 066 067 @Override 068 public MetadataType getType() 069 { 070 return MetadataType.LONG; 071 } 072 073 @Override 074 public boolean isMultiple() 075 { 076 return false; 077 } 078 079 @Override 080 public boolean isSortable() 081 { 082 return true; 083 } 084 085 @Override 086 public Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters) 087 { 088 long stepId = parseLong(value); 089 if (stepId != 0) 090 { 091 return new WorkflowStepQuery(operator, (int) stepId); 092 } 093 094 return null; 095 } 096 097 @Override 098 public SearchField getSearchField() 099 { 100 return new WorkflowStepSearchField(); 101 } 102 103 @Override 104 public String getRenderer() 105 { 106 return "Ametys.cms.content.EditContentsGrid.renderWorkflowStep"; 107 } 108 109 @Override 110 public String getConverter() 111 { 112 return "Ametys.cms.content.EditContentsGrid.convertWorkflowStep"; 113 } 114 115 @Override 116 public Integer getColumnWidth() 117 { 118 return 60; 119 } 120 121 @Override 122 public Object getValue(Content content) 123 { 124 if (content instanceof WorkflowAwareContent) 125 { 126 WorkflowAwareContent waContent = (WorkflowAwareContent) content; 127 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent); 128 129 long workflowId = waContent.getWorkflowId(); 130 List<Step> currentSteps = workflow.getCurrentSteps(workflowId); 131 132 if (!currentSteps.isEmpty()) 133 { 134 return currentSteps.iterator().next().getStepId(); 135 } 136 } 137 138 return null; 139 } 140 141 @Override 142 public Object getFullValue(Content content) 143 { 144 Map<String, Object> workflowInfos = new LinkedHashMap<>(); 145 146 if (content instanceof WorkflowAwareContent) 147 { 148 WorkflowAwareContent waContent = (WorkflowAwareContent) content; 149 AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent); 150 151 int currentStepId = 0; 152 153 long workflowId = waContent.getWorkflowId(); 154 Iterator<Step> currentSteps = workflow.getCurrentSteps(workflowId).iterator(); 155 156 while (currentSteps.hasNext()) 157 { 158 Step step = currentSteps.next(); 159 currentStepId = step.getStepId(); 160 } 161 162 String workflowName = workflow.getWorkflowName(workflowId); 163 WorkflowDescriptor workflowDescriptor = workflow.getWorkflowDescriptor(workflowName); 164 165 if (workflowDescriptor != null) 166 { 167 StepDescriptor stepDescriptor = workflowDescriptor.getStep(currentStepId); 168 if (stepDescriptor != null) 169 { 170 I18nizableText workflowStepName = new I18nizableText("application", stepDescriptor.getName()); 171 172 workflowInfos.put("stepId", currentStepId); 173 workflowInfos.put("name", workflowStepName); 174 175 String[] icons = new String[] {"small", "medium", "large"}; 176 for (String icon : icons) 177 { 178 if ("application".equals(workflowStepName.getCatalogue())) 179 { 180 workflowInfos.put(icon + "Icon", "/plugins/cms/resources_workflow/" + workflowStepName.getKey() + "-" + icon + ".png"); 181 } 182 else 183 { 184 String pluginName = workflowStepName.getCatalogue().substring("plugin.".length()); 185 workflowInfos.put(icon + "Icon", "/plugins/" + pluginName + "/resources/img/workflow/" + workflowStepName.getKey() + "-" + icon + ".png"); 186 } 187 } 188 } 189 else if (getLogger().isWarnEnabled()) 190 { 191 getLogger().warn("Unknown step id '" + currentStepId + "' for workflow for name : " + workflowName); 192 } 193 } 194 else if (getLogger().isWarnEnabled()) 195 { 196 getLogger().warn("Unknown workflow for name : " + workflowName); 197 } 198 } 199 200 return workflowInfos; 201 } 202 203 @Override 204 public EnumeratorDefinition getEnumeratorDefinition(Collection<String> contentTypes, Configuration configuration) 205 { 206 DefaultConfiguration conf = new DefaultConfiguration("criteria"); 207 208 String workflowName = configuration.getChild("workflow").getAttribute("name", "content"); 209 210 DefaultConfiguration enumConf = new DefaultConfiguration("enumeration"); 211 212 DefaultConfiguration customEnumerator = new DefaultConfiguration("custom-enumerator"); 213 customEnumerator.setAttribute("class", DefaultWorkflowStepEnumerator.class.getName()); 214 enumConf.addChild(customEnumerator); 215 216 DefaultConfiguration wfNameConf = new DefaultConfiguration("workflow-name"); 217 wfNameConf.setValue(workflowName); 218 customEnumerator.addChild(wfNameConf); 219 220 DefaultConfiguration excludeConf = new DefaultConfiguration("exclude-workflow-steps"); 221 222 // Exclude workflow steps greater than 9000 223 List<StepDescriptor> steps = _workflowHelper.getWorkflowDescriptor(workflowName).getSteps(); 224 for (StepDescriptor stepDescriptor : steps) 225 { 226 if (stepDescriptor.getId() >= 9000) 227 { 228 DefaultConfiguration stepId = new DefaultConfiguration("id"); 229 stepId.setValue(stepDescriptor.getId()); 230 excludeConf.addChild(stepId); 231 } 232 } 233 234 customEnumerator.addChild(excludeConf); 235 236 conf.addChild(enumConf); 237 238 return new EnumeratorDefinition(DefaultWorkflowStepEnumerator.class, conf); 239 } 240 241}