Java tutorial
/******************************************************************************* * Copyright (C) 2005-2013 Alfresco Software Limited. * * This file is part of the Alfresco Mobile SDK. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.alfresco.mobile.android.api.services.impl.onpremise; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.alfresco.mobile.android.api.constants.OnPremiseConstant; import org.alfresco.mobile.android.api.constants.WorkflowModel; import org.alfresco.mobile.android.api.exceptions.ErrorCodeRegistry; import org.alfresco.mobile.android.api.model.ContentStream; import org.alfresco.mobile.android.api.model.Document; import org.alfresco.mobile.android.api.model.ListingContext; import org.alfresco.mobile.android.api.model.ListingFilter; import org.alfresco.mobile.android.api.model.Node; import org.alfresco.mobile.android.api.model.PagingResult; import org.alfresco.mobile.android.api.model.Person; import org.alfresco.mobile.android.api.model.Process; import org.alfresco.mobile.android.api.model.ProcessDefinition; import org.alfresco.mobile.android.api.model.SearchLanguage; import org.alfresco.mobile.android.api.model.Task; import org.alfresco.mobile.android.api.model.impl.ContentStreamImpl; import org.alfresco.mobile.android.api.model.impl.PagingResultImpl; import org.alfresco.mobile.android.api.model.impl.ProcessDefinitionImpl; import org.alfresco.mobile.android.api.model.impl.ProcessImpl; import org.alfresco.mobile.android.api.model.impl.TaskImpl; import org.alfresco.mobile.android.api.services.impl.AbstractWorkflowService; import org.alfresco.mobile.android.api.session.AlfrescoSession; import org.alfresco.mobile.android.api.session.impl.RepositorySessionImpl; import org.alfresco.mobile.android.api.utils.DateUtils; import org.alfresco.mobile.android.api.utils.JsonDataWriter; import org.alfresco.mobile.android.api.utils.JsonUtils; import org.alfresco.mobile.android.api.utils.NodeRefUtils; import org.alfresco.mobile.android.api.utils.OnPremiseUrlRegistry; import org.alfresco.mobile.android.api.utils.messages.Messagesl18n; import org.apache.chemistry.opencmis.client.bindings.spi.http.Output; import org.apache.chemistry.opencmis.client.bindings.spi.http.Response; import org.apache.chemistry.opencmis.commons.impl.JSONConverter; import org.apache.chemistry.opencmis.commons.impl.UrlBuilder; import org.apache.chemistry.opencmis.commons.impl.json.JSONObject; import org.json.JSONArray; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; /** * Specific implementation of WorkflowService for OnPremise API. * * @since 1.3 * @author Jean Marie Pascal */ public class OnPremiseWorkflowServiceImpl extends AbstractWorkflowService { private static final String TAG = OnPremiseWorkflowServiceImpl.class.getName(); public OnPremiseWorkflowServiceImpl(AlfrescoSession repositorySession) { super(repositorySession); } // //////////////////////////////////////////////////////////////// // PROCESS DEFINITIONS // //////////////////////////////////////////////////////////////// @SuppressWarnings("unchecked") /** {@inheritDoc} */ public PagingResult<ProcessDefinition> getProcessDefinitions(ListingContext listingContext) { List<ProcessDefinition> definitions = new ArrayList<ProcessDefinition>(); Map<String, Object> json = new HashMap<String, Object>(0); boolean hasMoreItems = false; int size = 0; try { String link = OnPremiseUrlRegistry.getProcessDefinitionsUrl(session); UrlBuilder url = new UrlBuilder(link); // send and parse Response resp = read(url, ErrorCodeRegistry.WORKFLOW_GENERIC); json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { List<Object> jo = (List<Object>) json.get(OnPremiseConstant.DATA_VALUE); size = jo.size(); for (Object obj : jo) { definitions.add(ProcessDefinitionImpl.parseJson((Map<String, Object>) obj)); } if (listingContext != null) { int fromIndex = (listingContext.getSkipCount() > size) ? size : listingContext.getSkipCount(); // Case if skipCount > result size if (listingContext.getSkipCount() < size) { fromIndex = listingContext.getSkipCount(); } // Case if skipCount > result size if (listingContext.getMaxItems() + fromIndex >= size) { definitions = definitions.subList(fromIndex, size); hasMoreItems = false; } else { definitions = definitions.subList(fromIndex, listingContext.getMaxItems() + fromIndex); hasMoreItems = true; } } } } catch (Exception e) { convertException(e); } return new PagingResultImpl<ProcessDefinition>(definitions, hasMoreItems, size); } @SuppressWarnings("unchecked") /** {@inheritDoc} */ public ProcessDefinition getProcessDefinition(String processDefinitionIdentifier) { if (isStringNull(processDefinitionIdentifier)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "processDefinitionIdentifier")); } ProcessDefinition definition = null; try { if (session.getRepositoryInfo().getMajorVersion() >= OnPremiseConstant.ALFRESCO_VERSION_4) { String link = OnPremiseUrlRegistry.getProcessDefinitionUrl(session, processDefinitionIdentifier); UrlBuilder url = new UrlBuilder(link); // send and parse Response resp = read(url, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { Map<String, Object> jo = (Map<String, Object>) json.get(OnPremiseConstant.DATA_VALUE); definition = ProcessDefinitionImpl.parseJson(jo); } } else { List<ProcessDefinition> definitions = getProcessDefinitions(); for (ProcessDefinition processDefinition : definitions) { if (processDefinitionIdentifier.equals(processDefinition.getIdentifier())) { definition = processDefinition; break; } } } } catch (Exception e) { convertException(e); } return definition; } // //////////////////////////////////////////////////////////////// // PROCESS // //////////////////////////////////////////////////////////////// /** {@inheritDoc} */ public Process startProcess(ProcessDefinition processDefinition, List<Person> assignees, Map<String, Serializable> variables, List<Document> items) { if (isObjectNull(processDefinition)) { throw new IllegalArgumentException(String.format( Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "processDefinition")); } Process process = null; try { String link = OnPremiseUrlRegistry.getFormProcessUrl(session, processDefinition.getKey()); UrlBuilder url = new UrlBuilder(link); // prepare json data JSONObject jo = new JSONObject(); // ASSIGNEES // We need to retrieve the noderef associated to the person if (assignees != null && !assignees.isEmpty()) { if (assignees.size() == 1 && WorkflowModel.FAMILY_PROCESS_ADHOC.contains(processDefinition.getKey()) || WorkflowModel.FAMILY_PROCESS_REVIEW.contains(processDefinition.getKey())) { jo.put(OnPremiseConstant.ASSOC_BPM_ASSIGNEE_ADDED_VALUE, getPersonGUID(assignees.get(0))); } else if (WorkflowModel.FAMILY_PROCESS_PARALLEL_REVIEW.contains(processDefinition.getKey())) { List<String> guids = new ArrayList<String>(assignees.size()); for (Person p : assignees) { guids.add(getPersonGUID(p)); } jo.put(OnPremiseConstant.ASSOC_BPM_ASSIGNEES_ADDED_VALUE, TextUtils.join(",", guids)); } } // VARIABLES if (variables != null && !variables.isEmpty()) { for (Entry<String, Serializable> entry : variables.entrySet()) { if (ALFRESCO_TO_WORKFLOW.containsKey(entry.getKey())) { jo.put(ALFRESCO_TO_WORKFLOW.get(entry.getKey()), entry.getValue()); } else { jo.put(entry.getKey(), entry.getValue()); } } } // ITEMS if (items != null && !items.isEmpty()) { List<String> variablesItems = new ArrayList<String>(items.size()); for (Node node : items) { variablesItems.add(NodeRefUtils.getCleanIdentifier(node.getIdentifier())); } jo.put(OnPremiseConstant.ASSOC_PACKAGEITEMS_ADDED_VALUE, TextUtils.join(",", variablesItems.toArray(new String[0]))); } final JsonDataWriter dataWriter = new JsonDataWriter(jo); // send Response resp = post(url, dataWriter.getContentType(), new Output() { public void write(OutputStream out) throws IOException { dataWriter.write(out); } }, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); String data = JSONConverter.getString(json, OnPremiseConstant.PERSISTEDOBJECT_VALUE); // WorkflowInstance[id=activiti$18328,active=true,def=WorkflowDefinition[ String processId = data.split("\\[")[1].split(",")[0].split("=")[1]; process = getProcess(processId); } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); convertException(e); } return process; } /** {@inheritDoc} */ protected UrlBuilder getProcessUrl(Process process) { return new UrlBuilder(OnPremiseUrlRegistry.getProcessUrl(session, process.getIdentifier())); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") public PagingResult<Process> getProcesses(ListingContext listingContext) { List<Process> processes = new ArrayList<Process>(); Map<String, Object> json = new HashMap<String, Object>(0); int maxItems = -1; try { String link = OnPremiseUrlRegistry.getProcessesUrl(session); UrlBuilder url = new UrlBuilder(link); if (listingContext != null) { if (listingContext.getFilter() != null) { ListingFilter lf = listingContext.getFilter(); // Assignee if (lf.hasFilterValue(FILTER_KEY_INITIATOR)) { if (lf.getFilterValue(FILTER_KEY_INITIATOR) instanceof String) { url.addParameter(OnPremiseConstant.INITIATOR_VALUE, lf.getFilterValue(FILTER_KEY_INITIATOR)); } else if (lf.getFilterValue(FILTER_KEY_ASSIGNEE) instanceof Integer) { switch ((Integer) lf.getFilterValue(FILTER_KEY_INITIATOR)) { case FILTER_ASSIGNEE_ME: url.addParameter(OnPremiseConstant.INITIATOR_VALUE, session.getPersonIdentifier()); break; case FILTER_ASSIGNEE_ALL: break; default: break; } } } else { url.addParameter(OnPremiseConstant.INITIATOR_VALUE, session.getPersonIdentifier()); } if (lf.hasFilterValue(FILTER_KEY_PRIORITY)) { url.addParameter(OnPremiseConstant.PRIORITY_VALUE, lf.getFilterValue(FILTER_KEY_PRIORITY)); } if (lf.hasFilterValue(FILTER_KEY_STATUS)) { switch ((Integer) lf.getFilterValue(FILTER_KEY_STATUS)) { case FILTER_STATUS_COMPLETE: url.addParameter(OnPremiseConstant.STATE_VALUE, OnPremiseConstant.COMPLETED_UPPERCASE_VALUE); break; case FILTER_STATUS_ACTIVE: url.addParameter(OnPremiseConstant.STATE_VALUE, OnPremiseConstant.ACTIVE_UPPERCASE_VALUE); break; default: break; } } if (lf.hasFilterValue(FILTER_KEY_DUE)) { GregorianCalendar calendar = new GregorianCalendar(); calendar.set(Calendar.HOUR, 11); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); switch ((Integer) lf.getFilterValue(FILTER_KEY_DUE)) { case FILTER_DUE_TODAY: url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); calendar.add(Calendar.DAY_OF_MONTH, -1); url.addParameter(OnPremiseConstant.DUEAFTER_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_TOMORROW: url.addParameter(OnPremiseConstant.DUEAFTER_VALUE, DateUtils.format(calendar)); calendar.add(Calendar.DAY_OF_MONTH, 1); url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_7DAYS: url.addParameter(OnPremiseConstant.DUEAFTER_VALUE, DateUtils.format(calendar)); calendar.add(Calendar.DAY_OF_MONTH, 7); url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_OVERDUE: calendar.add(Calendar.DAY_OF_MONTH, -1); url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_NODATE: url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, ""); break; default: break; } } } url.addParameter(OnPremiseConstant.MAX_ITEMS_VALUE, listingContext.getMaxItems()); maxItems = listingContext.getMaxItems(); url.addParameter(OnPremiseConstant.SKIP_COUNT_VALUE, listingContext.getSkipCount()); } else { url.addParameter(OnPremiseConstant.STATE_VALUE, OnPremiseConstant.IN_PROGRESS_UPPERCASE_VALUE); } // send and parse Response resp = read(url, ErrorCodeRegistry.WORKFLOW_GENERIC); json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { List<Object> jo = (List<Object>) json.get(OnPremiseConstant.DATA_VALUE); for (Object obj : jo) { processes.add(ProcessImpl.parseJson((Map<String, Object>) obj)); } } } catch (Exception e) { convertException(e); } return new PagingResultImpl<Process>(processes, maxItems == -1, json.size()); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") public Process getProcess(String processId) { if (isStringNull(processId)) { throw new IllegalArgumentException(String .format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "processId")); } Process process = null; try { String link = OnPremiseUrlRegistry.getProcessUrl(session, processId); UrlBuilder url = new UrlBuilder(link); // send and parse Response resp = read(url, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { Map<String, Object> jo = (Map<String, Object>) json.get(OnPremiseConstant.DATA_VALUE); process = ProcessImpl.parseJson(jo); } } catch (Exception e) { convertException(e); } return process; } /** {@inheritDoc} */ public PagingResult<Task> getTasks(Process process, ListingContext listingContext) { if (isObjectNull(process)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "process")); } String link = OnPremiseUrlRegistry.getTasksForProcessIdUrl(session, process.getIdentifier()); if (listingContext != null && listingContext.getFilter() != null) { ListingFilter lf = listingContext.getFilter(); if (lf.hasFilterValue(FILTER_KEY_STATUS) && (Integer) lf.getFilterValue(FILTER_KEY_STATUS) == FILTER_STATUS_ANY) { link = OnPremiseUrlRegistry.getAllTasksForProcessIdUrl(session, process.getIdentifier()); } } return getTasks(link, listingContext); } /** {@inheritDoc} */ public Process refresh(Process process) { if (isObjectNull(process)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "process")); } return getProcess(process.getIdentifier()); } // //////////////////////////////////////////////////////////////// // ITEMS // //////////////////////////////////////////////////////////////// /** {@inheritDoc} */ public PagingResult<Document> getDocuments(Task task, ListingContext listingContext) { if (isObjectNull(task)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "task")); } if (isStringNull(task.getIdentifier())) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "taskId")); } return getItems(task.getIdentifier(), listingContext); } /** {@inheritDoc} */ public PagingResult<Document> getDocuments(Process process, ListingContext listingContext) { if (isObjectNull(process)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "process")); } if (isStringNull(process.getIdentifier())) { throw new IllegalArgumentException(String .format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "processId")); } try { ListingContext lc = new ListingContext(); lc.setMaxItems(1); PagingResult<Task> tasks = getTasks(process, lc); if (tasks.getTotalItems() > 0) { return getItems(tasks.getList().get(0).getIdentifier(), listingContext); } } catch (Exception e) { convertException(e); } return getItems(process.getIdentifier(), listingContext); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") protected PagingResult<Document> getItems(String id, ListingContext listingContext) { List<Document> nodes = new ArrayList<Document>(); try { String link = OnPremiseUrlRegistry.getProcessItemsUrl(session, id); UrlBuilder url = new UrlBuilder(link); // prepare json data JSONObject jo = new JSONObject(); jo.put(OnPremiseConstant.ITEMKIND_VALUE, OnPremiseConstant.TASK_VALUE); jo.put(OnPremiseConstant.ITEMID_VALUE, id); ArrayList<String> fields = new ArrayList<String>(); fields.add(OnPremiseConstant.PACKAGEITEMS_VALUE); jo.put(OnPremiseConstant.FIELDS_VALUE, new JSONArray(fields)); final JsonDataWriter dataWriter = new JsonDataWriter(jo); // send Response resp = post(url, dataWriter.getContentType(), new Output() { public void write(OutputStream out) throws IOException { dataWriter.write(out); } }, ErrorCodeRegistry.WORKFLOW_GENERIC); // parse Map<String, Object> formData = null; Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { Map<String, Object> data = (Map<String, Object>) json.get(OnPremiseConstant.DATA_VALUE); formData = (Map<String, Object>) data.get(OnPremiseConstant.FORMDATA_VALUE); } if (formData != null && formData.containsKey(OnPremiseConstant.ASSOC_PACKAGEITEMS_VALUE) && !((String) formData.get(OnPremiseConstant.ASSOC_PACKAGEITEMS_VALUE)).isEmpty()) { // Retrieve node object based on nodeId String[] values = ((String) formData.get(OnPremiseConstant.ASSOC_PACKAGEITEMS_VALUE)).split(","); StringBuilder builder = new StringBuilder("SELECT * FROM cmis:document WHERE cmis:objectId="); JsonUtils.join(builder, " OR cmis:objectId=", values); List<Node> nodesN = session.getServiceRegistry().getSearchService().search(builder.toString(), SearchLanguage.CMIS); for (Node node : nodesN) { nodes.add((Document) node); } } } catch (Exception e) { convertException(e); } return new PagingResultImpl<Document>(nodes, false, nodes.size()); } /** {@inheritDoc} */ public void addDocuments(Task task, List<Document> items) { updateDocuments(task, items, true); } /** {@inheritDoc} */ public void removeDocuments(Task task, List<Document> items) { updateDocuments(task, items, false); } /** * @param task * @param items * @param isAddition */ private void updateDocuments(Task task, List<Document> items, boolean isAddition) { try { String variableKey = OnPremiseConstant.ASSOC_PACKAGEITEMS_REMOVED_VALUE; if (isAddition) { variableKey = OnPremiseConstant.ASSOC_PACKAGEITEMS_ADDED_VALUE; } List<String> variablesItems = new ArrayList<String>(items.size()); for (Node node : items) { variablesItems.add(NodeRefUtils.getCleanIdentifier(node.getIdentifier())); } Map<String, Serializable> variables = new HashMap<String, Serializable>(); variables.put(variableKey, TextUtils.join(",", variablesItems.toArray(new String[0]))); updateVariables(task, variables); } catch (Exception e) { convertException(e); } } // //////////////////////////////////////////////////////////////// // TASKS // //////////////////////////////////////////////////////////////// /** {@inheritDoc} */ @SuppressWarnings("unchecked") private PagingResult<Task> getTasks(String link, ListingContext listingContext) { List<Task> tasks = new ArrayList<Task>(); Map<String, Object> json = new HashMap<String, Object>(0); int maxItems = -1; int size = 0; try { UrlBuilder url = new UrlBuilder(link); if (listingContext != null) { if (listingContext.getFilter() != null) { ListingFilter lf = listingContext.getFilter(); // Assignee if (lf.hasFilterValue(FILTER_KEY_ASSIGNEE)) { if (lf.getFilterValue(FILTER_KEY_ASSIGNEE) instanceof String) { url.addParameter(OnPremiseConstant.AUTHORITY_VALUE, lf.getFilterValue(FILTER_KEY_ASSIGNEE)); } else if (lf.getFilterValue(FILTER_KEY_ASSIGNEE) instanceof Integer) { switch ((Integer) lf.getFilterValue(FILTER_KEY_ASSIGNEE)) { case FILTER_ASSIGNEE_UNASSIGNED: url.addParameter(OnPremiseConstant.AUTHORITY_VALUE, session.getPersonIdentifier()); url.addParameter(OnPremiseConstant.POOLEDTASKS_VALUE, true); break; case FILTER_ASSIGNEE_ME: url.addParameter(OnPremiseConstant.AUTHORITY_VALUE, session.getPersonIdentifier()); url.addParameter(OnPremiseConstant.POOLEDTASKS_VALUE, false); break; case FILTER_ASSIGNEE_ALL: url.addParameter(OnPremiseConstant.AUTHORITY_VALUE, session.getPersonIdentifier()); break; case FILTER_NO_ASSIGNEE: break; default: break; } } } else { url.addParameter(OnPremiseConstant.AUTHORITY_VALUE, session.getPersonIdentifier()); } if (lf.hasFilterValue(FILTER_KEY_PRIORITY)) { url.addParameter(OnPremiseConstant.PRIORITY_VALUE, lf.getFilterValue(FILTER_KEY_PRIORITY)); } if (lf.hasFilterValue(FILTER_KEY_STATUS)) { switch ((Integer) lf.getFilterValue(FILTER_KEY_STATUS)) { case FILTER_STATUS_COMPLETE: url.addParameter(OnPremiseConstant.STATE_VALUE, OnPremiseConstant.COMPLETED_UPPERCASE_VALUE); break; case FILTER_STATUS_ACTIVE: url.addParameter(OnPremiseConstant.STATE_VALUE, OnPremiseConstant.IN_PROGRESS_UPPERCASE_VALUE); break; case FILTER_STATUS_ANY: url.addParameter(OnPremiseConstant.INCLUDETASKS_VALUE, "true"); break; default: break; } } if (lf.hasFilterValue(FILTER_KEY_DUE)) { GregorianCalendar calendar = new GregorianCalendar(); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); switch ((Integer) lf.getFilterValue(FILTER_KEY_DUE)) { case FILTER_DUE_TODAY: url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); calendar.add(Calendar.DAY_OF_MONTH, -1); url.addParameter(OnPremiseConstant.DUEAFTER_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_TOMORROW: url.addParameter(OnPremiseConstant.DUEAFTER_VALUE, DateUtils.format(calendar)); calendar.add(Calendar.DAY_OF_MONTH, 1); url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_7DAYS: url.addParameter(OnPremiseConstant.DUEAFTER_VALUE, DateUtils.format(calendar)); calendar.add(Calendar.DAY_OF_MONTH, 7); url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_OVERDUE: calendar.add(Calendar.DAY_OF_MONTH, -1); url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, DateUtils.format(calendar)); break; case FILTER_DUE_NODATE: url.addParameter(OnPremiseConstant.DUEBEFORE_VALUE, ""); break; default: break; } } } url.addParameter(OnPremiseConstant.MAX_ITEMS_VALUE, listingContext.getMaxItems()); maxItems = listingContext.getMaxItems(); url.addParameter(OnPremiseConstant.SKIP_COUNT_VALUE, listingContext.getSkipCount()); } else { url.addParameter(OnPremiseConstant.STATE_VALUE, OnPremiseConstant.IN_PROGRESS_UPPERCASE_VALUE); } Log.d(TAG, url.toString()); // send and parse Response resp = read(url, ErrorCodeRegistry.WORKFLOW_GENERIC); json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { List<Object> jo = null; if (json.get(OnPremiseConstant.DATA_VALUE) instanceof List) { jo = (List<Object>) json.get(OnPremiseConstant.DATA_VALUE); } else if (json.get(OnPremiseConstant.DATA_VALUE) instanceof Map) { Map<String, Object> jso = (Map<String, Object>) json.get(OnPremiseConstant.DATA_VALUE); jo = (List<Object>) jso.get(OnPremiseConstant.TASKS_VALUE); } size = jo.size(); for (Object obj : jo) { tasks.add(TaskImpl.parseJson((Map<String, Object>) obj)); } } } catch (Exception e) { convertException(e); } return new PagingResultImpl<Task>(tasks, maxItems != -1, size); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") public Task getTask(String taskIdentifier) { if (isStringNull(taskIdentifier)) { throw new IllegalArgumentException(String.format( Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "taskIdentifier")); } Task task = null; try { String link = OnPremiseUrlRegistry.getTaskUrl(session, taskIdentifier); UrlBuilder url = new UrlBuilder(link); // send and parse Response resp = read(url, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { Map<String, Object> jo = (Map<String, Object>) json.get(OnPremiseConstant.DATA_VALUE); task = TaskImpl.parseJson(jo); } } catch (Exception e) { convertException(e); } return task; } /** {@inheritDoc} */ public PagingResult<Task> getTasks(ListingContext listingContext) { return getTasks(OnPremiseUrlRegistry.getTasksUrl(session), listingContext); } /** {@inheritDoc} */ public Task completeTask(Task task, Map<String, Serializable> variables) { if (isObjectNull(task)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "task")); } Map<String, Serializable> internalVariables = new HashMap<String, Serializable>(); if (variables != null) { internalVariables.putAll(variables); } Task resultTask = task; try { String link = OnPremiseUrlRegistry.getFormTaskUrl(session, task.getIdentifier()); UrlBuilder url = new UrlBuilder(link); // prepare json data JSONObject jo = new JSONObject(); // TRANSITION if (!internalVariables.containsKey(WorkflowModel.PROP_TRANSITIONS_VALUE)) { String transitionIdentifier = ""; if (task.getIdentifier().startsWith(WorkflowModel.KEY_PREFIX_ACTIVITI)) { transitionIdentifier = WorkflowModel.TRANSITION_NEXT; } internalVariables.put(WorkflowModel.PROP_TRANSITIONS_VALUE, transitionIdentifier); } // VARIABLES if (internalVariables != null && !internalVariables.isEmpty()) { for (Entry<String, Serializable> entry : internalVariables.entrySet()) { if (ALFRESCO_TO_WORKFLOW.containsKey(entry.getKey())) { jo.put(ALFRESCO_TO_WORKFLOW.get(entry.getKey()), entry.getValue()); } } } final JsonDataWriter dataWriter = new JsonDataWriter(jo); // send Response resp = post(url, dataWriter.getContentType(), new Output() { public void write(OutputStream out) throws IOException { dataWriter.write(out); } }, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); String data = JSONConverter.getString(json, OnPremiseConstant.PERSISTEDOBJECT_VALUE); // WorkflowInstance[id=activiti$18328,active=true,def=WorkflowDefinition[ String taskId = data.split("\\[")[1].split(",")[0].split("=")[1]; resultTask = getTask(taskId); } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); convertException(e); } return resultTask; } /** {@inheritDoc} */ public Task refresh(Task task) { if (isObjectNull(task)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "task")); } return getTask(task.getIdentifier()); } /** {@inheritDoc} */ public Task claimTask(Task task) { if (isObjectNull(task)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "task")); } try { return changeAssignee(task.getIdentifier(), session.getPersonIdentifier()); } catch (Exception e) { convertException(e); } return null; } /** {@inheritDoc} */ public Task unClaimTask(Task task) { if (isObjectNull(task)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "task")); } try { return changeAssignee(task.getIdentifier(), null); } catch (Exception e) { convertException(e); } return null; } /** {@inheritDoc} */ public Task reassignTask(Task task, Person assignee) { if (isObjectNull(task)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "task")); } if (isObjectNull(assignee)) { throw new IllegalArgumentException(String .format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "assignee")); } return changeAssignee(task.getIdentifier(), assignee.getIdentifier()); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") private Task changeAssignee(String taskId, String assigneeId) { Task updatedTask = null; try { String link = OnPremiseUrlRegistry.getTaskUrl(session, taskId); UrlBuilder url = new UrlBuilder(link); // prepare json data JSONObject jobject = new JSONObject(); jobject.put(WorkflowModel.PROP_OWNER, assigneeId); final JsonDataWriter dataWriter = new JsonDataWriter(jobject); // send Response resp = put(url, dataWriter.getContentType(), null, new Output() { public void write(OutputStream out) throws IOException { dataWriter.write(out); } }, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { Map<String, Object> jo = (Map<String, Object>) json.get(OnPremiseConstant.DATA_VALUE); updatedTask = TaskImpl.parseJson(jo); } } catch (Exception e) { convertException(e); } return updatedTask; } // //////////////////////////////////////////////////////////////// // VARIABLES // //////////////////////////////////////////////////////////////// /** {@inheritDoc} */ public Task updateVariables(Task task, Map<String, Serializable> variables) { if (isObjectNull(task)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "task")); } Map<String, Serializable> internalVariables = new HashMap<String, Serializable>(); if (variables != null) { internalVariables.putAll(variables); } Task resultTask = task; try { String link = OnPremiseUrlRegistry.getFormTaskUrl(session, task.getIdentifier()); UrlBuilder url = new UrlBuilder(link); // prepare json data JSONObject jo = new JSONObject(); // VARIABLES if (internalVariables != null && !internalVariables.isEmpty()) { for (Entry<String, Serializable> entry : internalVariables.entrySet()) { if (ALFRESCO_TO_WORKFLOW.containsKey(entry.getKey())) { jo.put(ALFRESCO_TO_WORKFLOW.get(entry.getKey()), entry.getValue()); } else { jo.put(entry.getKey(), entry.getValue()); } } } final JsonDataWriter dataWriter = new JsonDataWriter(jo); // send Response resp = post(url, dataWriter.getContentType(), new Output() { public void write(OutputStream out) throws IOException { dataWriter.write(out); } }, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); String data = JSONConverter.getString(json, OnPremiseConstant.PERSISTEDOBJECT_VALUE); // WorkflowInstance[id=activiti$18328,active=true,def=WorkflowDefinition[ String taskId = data.split("\\[")[1].split(",")[0].split("=")[1]; resultTask = getTask(taskId); } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); convertException(e); } return resultTask; } // //////////////////////////////////////////////////////////////// // DIAGRAM // //////////////////////////////////////////////////////////////// @Override public UrlBuilder getProcessDiagramUrl(String processId) { String url = OnPremiseUrlRegistry.getWorkflowDiagram(session, processId); return new UrlBuilder(url); } /** {@inheritDoc} */ public ContentStream getProcessDiagram(Process process) { if (isObjectNull(process)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "process")); } return getProcessDiagram(process.getIdentifier()); } /** {@inheritDoc} */ public ContentStream getProcessDiagram(String processId) { if (isStringNull(processId)) { throw new IllegalArgumentException(String .format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "processId")); } try { ContentStream cf = null; String url = OnPremiseUrlRegistry.getWorkflowDiagram(session, processId); UrlBuilder builder = new UrlBuilder(url); Response resp = read(builder, ErrorCodeRegistry.WORKFLOW_GENERIC); cf = new ContentStreamImpl(resp.getStream(), resp.getContentTypeHeader(), resp.getContentLength().longValue()); return cf; } catch (Exception e) { convertException(e); } return null; } // //////////////////////////////////////////////////// // Person Utils // //////////////////////////////////////////////////// /** * @param person * @return */ @SuppressWarnings("unchecked") private String getPersonGUID(Person person) { if (isObjectNull(person)) { throw new IllegalArgumentException( String.format(Messagesl18n.getString("ErrorCodeRegistry.GENERAL_INVALID_ARG_NULL"), "person")); } String guid = null; try { String url = OnPremiseUrlRegistry.getPersonGUIDUrl(session, person.getIdentifier()); UrlBuilder builder = new UrlBuilder(url); Response resp = read(builder, ErrorCodeRegistry.WORKFLOW_GENERIC); Map<String, Object> json = JsonUtils.parseObject(resp.getStream(), resp.getCharset()); if (json != null) { Map<String, Object> data = (Map<String, Object>) json.get(OnPremiseConstant.DATA_VALUE); List<Object> jo = (List<Object>) data.get(OnPremiseConstant.ITEMS_VALUE); if (jo != null && jo.size() == 1) { guid = JSONConverter.getString((Map<String, Object>) jo.get(0), OnPremiseConstant.NODEREF_VALUE); } } } catch (Exception e) { convertException(e); } return guid; } // //////////////////////////////////////////////////// // Mapping between workflowModel and real implementation // //////////////////////////////////////////////////// /** Alfresco Form extension prefix . */ private static final String FORM_PREFIX = "prop_"; /** * */ private static final Map<String, String> ALFRESCO_TO_WORKFLOW = new HashMap<String, String>(); static { ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, FORM_PREFIX.concat(WorkflowModel.PROP_WORKFLOW_DESCRIPTION)); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_WORKFLOW_DUE_DATE, FORM_PREFIX.concat(WorkflowModel.PROP_WORKFLOW_DUE_DATE)); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_WORKFLOW_PRIORITY, FORM_PREFIX.concat(WorkflowModel.PROP_WORKFLOW_PRIORITY)); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_SEND_EMAIL_NOTIFICATIONS, FORM_PREFIX.concat(WorkflowModel.PROP_SEND_EMAIL_NOTIFICATIONS)); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_COMMENT, FORM_PREFIX.concat(WorkflowModel.PROP_COMMENT)); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_STATUS, FORM_PREFIX.concat(WorkflowModel.PROP_STATUS)); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_REVIEW_OUTCOME, FORM_PREFIX.concat(WorkflowModel.PROP_REVIEW_OUTCOME)); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_TRANSITIONS_VALUE, WorkflowModel.PROP_TRANSITIONS_VALUE); ALFRESCO_TO_WORKFLOW.put(WorkflowModel.PROP_REQUIRED_APPROVE_PERCENT, FORM_PREFIX.concat(WorkflowModel.PROP_REQUIRED_APPROVE_PERCENT)); } // //////////////////////////////////////////////////// // Save State - serialization / deserialization // //////////////////////////////////////////////////// public static final Parcelable.Creator<OnPremiseWorkflowServiceImpl> CREATOR = new Parcelable.Creator<OnPremiseWorkflowServiceImpl>() { public OnPremiseWorkflowServiceImpl createFromParcel(Parcel in) { return new OnPremiseWorkflowServiceImpl(in); } public OnPremiseWorkflowServiceImpl[] newArray(int size) { return new OnPremiseWorkflowServiceImpl[size]; } }; public OnPremiseWorkflowServiceImpl(Parcel o) { super((AlfrescoSession) o.readParcelable(RepositorySessionImpl.class.getClassLoader())); } }