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