001/*
002 * (C) Copyright 2011-2016 Nuxeo SA (http://nuxeo.com/) and others.
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 *
016 * Contributors:
017 *     Nicolas Ulrich
018 */
019package org.nuxeo.ecm.platform.task;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.Calendar;
025import java.util.Date;
026import java.util.HashMap;
027import java.util.List;
028import java.util.Map;
029import java.util.Map.Entry;
030
031import org.nuxeo.ecm.core.api.CoreSession;
032import org.nuxeo.ecm.core.api.DocumentModel;
033import org.nuxeo.ecm.core.api.LifeCycleException;
034
035/**
036 * @since 5.5
037 */
038public class TaskImpl implements Task {
039
040    private static final long serialVersionUID = 1L;
041
042    private DocumentModel doc;
043
044    public TaskImpl(DocumentModel doc) {
045        this.doc = doc;
046    }
047
048    @Override
049    public void addComment(String author, String text) {
050        List<Map<String, Serializable>> existingTasks = getPropertyValue(TaskConstants.TASK_COMMENTS_PROPERTY_NAME);
051        if (existingTasks == null) {
052            existingTasks = new ArrayList<>();
053        }
054        existingTasks.add(new TaskComment(author, text));
055        setPropertyValue(TaskConstants.TASK_COMMENTS_PROPERTY_NAME, existingTasks);
056    }
057
058    @Override
059    public void cancel(CoreSession coreSession) {
060        followTransition(coreSession, TaskConstants.TASK_CANCEL_LIFE_CYCLE_TRANSITION);
061    }
062
063    @Override
064    public void end(CoreSession coreSession) {
065        followTransition(coreSession, TaskConstants.TASK_END_LIFE_CYCLE_TRANSITION);
066    }
067
068    protected void followTransition(CoreSession coreSession, String transition) throws LifeCycleException {
069        if (coreSession.getAllowedStateTransitions(doc.getRef()).contains(transition)) {
070            coreSession.followTransition(doc.getRef(), transition);
071        } else {
072            throw new LifeCycleException(
073                    "Cannot follow transition " + transition + " on the document " + doc.getPathAsString());
074        }
075
076    }
077
078    @Override
079    public List<String> getActors() {
080        return getPropertyValue(TaskConstants.TASK_USERS_PROPERTY_NAME);
081    }
082
083    @Override
084    public List<TaskComment> getComments() {
085        List<Map<String, Serializable>> taskCommentsProperty = getPropertyValue(
086                TaskConstants.TASK_COMMENTS_PROPERTY_NAME);
087        List<TaskComment> taskComments = new ArrayList<>(taskCommentsProperty.size());
088        for (Map<String, Serializable> taskCommentMap : taskCommentsProperty) {
089            taskComments.add(new TaskComment(taskCommentMap));
090        }
091        return taskComments;
092    }
093
094    @Override
095    public Date getCreated() {
096        return getDatePropertyValue(TaskConstants.TASK_CREATED_PROPERTY_NAME);
097    }
098
099    protected Date getDatePropertyValue(String propertyName) {
100        Calendar cal = (Calendar) doc.getPropertyValue(propertyName);
101        if (cal != null) {
102            return cal.getTime();
103        }
104        return null;
105    }
106
107    @Override
108    public List<String> getDelegatedActors() {
109        return getPropertyValue(TaskConstants.TASK_DELEGATED_ACTORS_PROPERTY_NAME);
110    }
111
112    @Override
113    public String getDescription() {
114        return getPropertyValue(TaskConstants.TASK_DESCRIPTION_PROPERTY_NAME);
115    }
116
117    @Override
118    public String getDirective() {
119        return getPropertyValue(TaskConstants.TASK_DIRECTIVE_PROPERTY_NAME);
120
121    }
122
123    @Override
124    public DocumentModel getDocument() {
125        return doc;
126    }
127
128    @Override
129    public Date getDueDate() {
130        return getDatePropertyValue(TaskConstants.TASK_DUE_DATE_PROPERTY_NAME);
131
132    }
133
134    @Override
135    public String getId() {
136        return doc.getId();
137    }
138
139    @Override
140    public String getInitiator() {
141        return getPropertyValue(TaskConstants.TASK_INITIATOR_PROPERTY_NAME);
142    }
143
144    @Override
145    public String getName() {
146        return getPropertyValue(TaskConstants.TASK_NAME_PROPERTY_NAME);
147    }
148
149    @Override
150    public String getProcessId() {
151        return getPropertyValue(TaskConstants.TASK_PROCESS_ID_PROPERTY_NAME);
152    }
153
154    /**
155     * @since 7.4
156     */
157    @Override
158    public String getProcessName() {
159        return getPropertyValue(TaskConstants.TASK_PROCESS_NAME_PROPERTY_NAME);
160    }
161
162    @SuppressWarnings("unchecked")
163    protected <T> T getPropertyValue(String propertyName) {
164        Serializable value = doc.getPropertyValue(propertyName);
165        if (value instanceof Object[]) {
166            value = new ArrayList<>(Arrays.asList((Object[]) value));
167        }
168        return (T) value;
169    }
170
171    @Override
172    public List<String> getTargetDocumentsIds() {
173        return getPropertyValue(TaskConstants.TASK_TARGET_DOCUMENTS_IDS_PROPERTY_NAME);
174    }
175
176    @Override
177    public String getType() {
178        return getPropertyValue(TaskConstants.TASK_TYPE_PROPERTY_NAME);
179    }
180
181    @Override
182    public String getVariable(String key) {
183        Map<String, String> variables = getVariables();
184        return variables.get(key);
185    }
186
187    @Override
188    public Map<String, String> getVariables() {
189        List<Map<String, String>> variables = getPropertyValue(TaskConstants.TASK_VARIABLES_PROPERTY_NAME);
190        Map<String, String> variableMap = new HashMap<>(variables.size());
191        for (Map<String, String> map : variables) {
192            variableMap.put(map.get("key"), map.get("value"));
193        }
194        return variableMap;
195    }
196
197    @Override
198    public Boolean hasEnded() {
199        return TaskConstants.TASK_ENDED_LIFE_CYCLE_STATE.equals(doc.getCurrentLifeCycleState());
200    }
201
202    @Override
203    public Boolean isAccepted() {
204        Boolean isAccepted = getPropertyValue(TaskConstants.TASK_ACCEPTED_PROPERTY_NAME);
205        return isAccepted == null ? false : isAccepted;
206    }
207
208    @Override
209    public Boolean isCancelled() {
210        return TaskConstants.TASK_CANCELLED_LIFE_CYCLE_STATE.equals(doc.getCurrentLifeCycleState());
211    }
212
213    @Override
214    public Boolean isOpened() {
215        return TaskConstants.TASK_OPENED_LIFE_CYCLE_STATE.equals(doc.getCurrentLifeCycleState());
216    }
217
218    @Override
219    public void setAccepted(Boolean accepted) {
220        setPropertyValue(TaskConstants.TASK_ACCEPTED_PROPERTY_NAME, accepted);
221    }
222
223    @Override
224    public void setActors(List<String> users) {
225        setPropertyValue(TaskConstants.TASK_USERS_PROPERTY_NAME, users);
226    }
227
228    @Override
229    public void setCreated(Date created) {
230        setPropertyValue(TaskConstants.TASK_CREATED_PROPERTY_NAME, created);
231    }
232
233    @Override
234    public void setDelegatedActors(List<String> delegatedActors) {
235        setPropertyValue(TaskConstants.TASK_DELEGATED_ACTORS_PROPERTY_NAME, delegatedActors);
236    }
237
238    @Override
239    public void setDescription(String description) {
240        setPropertyValue(TaskConstants.TASK_DESCRIPTION_PROPERTY_NAME, description);
241    }
242
243    @Override
244    public void setDirective(String directive) {
245        setPropertyValue(TaskConstants.TASK_DIRECTIVE_PROPERTY_NAME, directive);
246    }
247
248    @Override
249    public void setDueDate(Date dueDate) {
250        setPropertyValue(TaskConstants.TASK_DUE_DATE_PROPERTY_NAME, dueDate);
251
252    }
253
254    @Override
255    public void setInitiator(String initiator) {
256        setPropertyValue(TaskConstants.TASK_INITIATOR_PROPERTY_NAME, initiator);
257    }
258
259    @Override
260    public void setName(String name) {
261        setPropertyValue(TaskConstants.TASK_NAME_PROPERTY_NAME, name);
262    }
263
264    @Override
265    public void setProcessId(String processId) {
266        setPropertyValue(TaskConstants.TASK_PROCESS_ID_PROPERTY_NAME, processId);
267    }
268
269    /**
270     * @since 7.4
271     */
272    @Override
273    public void setProcessName(String processName) {
274        setPropertyValue(TaskConstants.TASK_PROCESS_NAME_PROPERTY_NAME, processName);
275    }
276
277    protected void setPropertyValue(String propertyName, Object value) {
278        if (value != null) {
279            if (value instanceof Date) {
280                Calendar cal = Calendar.getInstance();
281                cal.setTime((Date) value);
282                doc.setPropertyValue(propertyName, cal);
283            } else {
284                doc.setPropertyValue(propertyName, (Serializable) value);
285            }
286        }
287    }
288
289    @Override
290    public void setTargetDocumentsIds(List<String> ids) {
291        setPropertyValue(TaskConstants.TASK_TARGET_DOCUMENTS_IDS_PROPERTY_NAME, ids);
292    }
293
294    @Override
295    public void setType(String type) {
296        setPropertyValue(TaskConstants.TASK_TYPE_PROPERTY_NAME, type);
297    }
298
299    @Override
300    public void setVariable(String key, String value) {
301        List<Map<String, Serializable>> variables = getPropertyValue(TaskConstants.TASK_VARIABLES_PROPERTY_NAME);
302        if (variables == null) {
303            variables = new ArrayList<>();
304        }
305        Map<String, Serializable> variableMap = new HashMap<>(2);
306        variableMap.put("key", key);
307        variableMap.put("value", value);
308        variables.add(variableMap);
309        setPropertyValue(TaskConstants.TASK_VARIABLES_PROPERTY_NAME, variables);
310    }
311
312    @Override
313    public void setVariables(Map<String, String> variables) {
314        List<Map<String, Serializable>> variablesProperty = getPropertyValue(
315                TaskConstants.TASK_VARIABLES_PROPERTY_NAME);
316        if (variablesProperty == null) {
317            variablesProperty = new ArrayList<>();
318        }
319        Map<String, Serializable> variable;
320        for (Entry<String, String> entry : variables.entrySet()) {
321            if (entry.getValue() != null) {
322                variable = new HashMap<>(2);
323                variable.put("key", entry.getKey());
324                variable.put("value", entry.getValue());
325                variablesProperty.add(variable);
326            }
327        }
328        setPropertyValue(TaskConstants.TASK_VARIABLES_PROPERTY_NAME, variablesProperty);
329    }
330
331}