/* * Copyright 2013 JBoss Inc * * 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.overlord.dtgov.ui.server.services.tasks; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import org.apache.commons.configuration.Configuration; import org.overlord.commons.config.JBossServer; import org.overlord.dtgov.taskapi.types.FindTasksRequest; import org.overlord.dtgov.taskapi.types.FindTasksResponse; import org.overlord.dtgov.taskapi.types.StatusType; import org.overlord.dtgov.taskapi.types.TaskDataType; import org.overlord.dtgov.taskapi.types.TaskDataType.Entry; import org.overlord.dtgov.taskapi.types.TaskSummaryType; import org.overlord.dtgov.taskapi.types.TaskType; import org.overlord.dtgov.taskclient.TaskApiClient; import org.overlord.dtgov.taskclient.auth.AuthenticationProvider; import org.overlord.dtgov.ui.client.shared.beans.TaskActionEnum; import org.overlord.dtgov.ui.client.shared.beans.TaskBean; import org.overlord.dtgov.ui.client.shared.beans.TaskInboxFilterBean; import org.overlord.dtgov.ui.client.shared.beans.TaskInboxResultSetBean; import org.overlord.dtgov.ui.client.shared.beans.TaskOwnerEnum; import org.overlord.dtgov.ui.client.shared.beans.TaskSummaryBean; import org.overlord.dtgov.ui.server.DtgovUIConfig; /** * An implementation of a task client that goes against the Task API defined in DtGov. * @author eric.wittmann@redhat.com */ public class DtGovTaskApiClient implements ITaskClient { private TaskApiClient client; /** * Constructor. */ public DtGovTaskApiClient(Configuration config) { String defaultTaskApiEndpoint = JBossServer.getBaseUrl() + "/dtgov/rest/tasks"; //$NON-NLS-1$ String endpoint = config.getString(DtgovUIConfig.TASK_API_ENDPOINT, defaultTaskApiEndpoint); AuthenticationProvider authProvider = null; String authProviderClass = config.getString(DtgovUIConfig.TASK_API_AUTH_PROVIDER); try { if (authProviderClass != null && authProviderClass.trim().length() > 0) { Class<?> c = Class.forName(authProviderClass); Constructor<?> constructor = null; try { constructor = c.getConstructor(Configuration.class); authProvider = (AuthenticationProvider) constructor.newInstance(config); } catch (NoSuchMethodException e) {} try { constructor = c.getConstructor(); authProvider = (AuthenticationProvider) constructor.newInstance(); } catch (NoSuchMethodException e) {} } client = new TaskApiClient(endpoint, authProvider); } catch (Exception e) { throw new RuntimeException(e); } } /** * @see org.overlord.dtgov.ui.server.services.tasks.ITaskClient#getTasks(org.overlord.dtgov.ui.client.shared.beans.TaskInboxFilterBean, int, int, java.lang.String, boolean) */ @Override public TaskInboxResultSetBean getTasks(TaskInboxFilterBean filters, int startIndex, int endIndex, String sortColumnId, boolean sortAscending) throws Exception { FindTasksRequest request = createFindTasksRequest(filters); request.setStartIndex(startIndex); request.setEndIndex(endIndex); request.setOrderBy(sortColumnId); request.setOrderAscending(sortAscending); FindTasksResponse findTasksResponse = client.findTasks(request); TaskInboxResultSetBean result = new TaskInboxResultSetBean(); result.setTasks(new ArrayList<TaskSummaryBean>()); for (TaskSummaryType taskSummaryType : findTasksResponse.getTaskSummary()) { TaskSummaryBean taskSummaryBean = convertToBean(taskSummaryType); result.getTasks().add(taskSummaryBean); } result.setItemsPerPage((endIndex - startIndex) + 1); result.setTotalResults(findTasksResponse.getTotalResults()); result.setStartIndex(startIndex); return result; } /** * @see org.overlord.dtgov.ui.server.services.tasks.ITaskClient#getTask(java.lang.String) */ @Override public TaskBean getTask(String taskId) throws Exception { TaskType task = client.getTask(taskId); return convertToBean(task); } /** * @see org.overlord.dtgov.ui.server.services.tasks.ITaskClient#updateTask(org.overlord.dtgov.ui.client.shared.beans.TaskBean) */ @Override public void updateTask(TaskBean task) throws Exception { // TODO implement updating a task!! what are the jbpm/dtgov capabilities here? } /** * @see org.overlord.dtgov.ui.server.services.tasks.ITaskClient#executeAction(org.overlord.dtgov.ui.client.shared.beans.TaskBean, org.overlord.dtgov.ui.client.shared.beans.TaskActionEnum) */ @Override public TaskBean executeAction(TaskBean task, TaskActionEnum action) throws Exception { TaskType updatedTask = null; if (action == TaskActionEnum.claim) { updatedTask = client.claimTask(task.getId()); } else if (action == TaskActionEnum.complete) { updatedTask = client.completeTask(task.getId(), task.getTaskData()); } else if (action == TaskActionEnum.start) { updatedTask = client.startTask(task.getId()); } else if (action == TaskActionEnum.stop) { updatedTask = client.stopTask(task.getId()); } else if (action == TaskActionEnum.release) { updatedTask = client.releaseTask(task.getId()); } else if (action == TaskActionEnum.fail) { updatedTask = client.failTask(task.getId(), task.getTaskData()); } return convertToBean(updatedTask); } /** * @throws DatatypeConfigurationException */ protected DatatypeFactory getXmlFactory() { try { return DatatypeFactory.newInstance(); } catch (DatatypeConfigurationException e) { throw new RuntimeException(e); } } /** * Converts the given task summary API object to a UI bean. * @param taskSummaryType */ private TaskSummaryBean convertToBean(TaskSummaryType taskSummaryType) { TaskSummaryBean bean = new TaskSummaryBean(); XMLGregorianCalendar dueDate = taskSummaryType.getDueDate(); if (dueDate != null) { bean.setDueDate(dueDate.toGregorianCalendar().getTime()); } bean.setId(taskSummaryType.getId()); bean.setName(taskSummaryType.getName()); bean.setOwner(taskSummaryType.getOwner()); bean.setPriority(taskSummaryType.getPriority()); bean.setStatus(taskSummaryType.getStatus().value()); return bean; } /** * Converts the given task API object to a UI bean. * @param taskSummaryType */ private TaskBean convertToBean(TaskType taskType) { TaskBean bean = new TaskBean(); XMLGregorianCalendar dueDate = taskType.getDueDate(); if (dueDate != null) { bean.setDueDate(dueDate.toGregorianCalendar().getTime()); } bean.setId(taskType.getId()); bean.setName(taskType.getName()); bean.setOwner(taskType.getOwner()); bean.setPriority(taskType.getPriority()); bean.setStatus(taskType.getStatus().value()); bean.setType(taskType.getType()); bean.setDescription(taskType.getDescription()); Map<String, String> taskData = new HashMap<String, String>(); TaskDataType data = taskType.getTaskData(); if (data != null) { List<Entry> entries = data.getEntry(); for (Entry entry : entries) { taskData.put(entry.getKey(), entry.getValue()); } } bean.setTaskData(taskData); assignAvailableActions(bean, taskType.getStatus()); return bean; } /** * Adds the available actions to the task bean based on the status of the task. * @param bean * @param status */ private void assignAvailableActions(TaskBean bean, StatusType status) { if (status == StatusType.COMPLETED || status == StatusType.FAILED || status == StatusType.ERROR) { // No actions available - tasks are complete. } else if (status == StatusType.READY) { bean.addAllowedAction(TaskActionEnum.claim); } else if (status == StatusType.IN_PROGRESS) { bean.addAllowedAction(TaskActionEnum.stop); bean.addAllowedAction(TaskActionEnum.complete); bean.addAllowedAction(TaskActionEnum.fail); } else if (status == StatusType.RESERVED) { bean.addAllowedAction(TaskActionEnum.release); bean.addAllowedAction(TaskActionEnum.start); } } /** * Creates a {@link FindTasksRequest} from the given task inbox filter bean. * @param filters */ protected FindTasksRequest createFindTasksRequest(TaskInboxFilterBean filters) { FindTasksRequest request = new FindTasksRequest(); if (filters.getPriority() >= 0) { request.getPriority().add(filters.getPriority()); } if (filters.getDateDueFrom() != null) { DatatypeFactory dtFactory = getXmlFactory(); GregorianCalendar cal = new GregorianCalendar(); cal.setTime(filters.getDateDueFrom()); XMLGregorianCalendar from = dtFactory.newXMLGregorianCalendar(cal); request.setDueOnFrom(from); } if (filters.getDateDueTo() != null) { DatatypeFactory dtFactory = getXmlFactory(); GregorianCalendar cal = new GregorianCalendar(); cal.setTime(filters.getDateDueTo()); XMLGregorianCalendar to = dtFactory.newXMLGregorianCalendar(cal); request.setDueOnTo(to); } TaskOwnerEnum owner = filters.getOwner(); if (owner == TaskOwnerEnum.any) { request.getStatus().add(StatusType.CREATED); request.getStatus().add(StatusType.READY); request.getStatus().add(StatusType.IN_PROGRESS); request.getStatus().add(StatusType.RESERVED); } else if (owner == TaskOwnerEnum.active) { request.getStatus().add(StatusType.IN_PROGRESS); } else if (owner == TaskOwnerEnum.mine) { request.getStatus().add(StatusType.IN_PROGRESS); request.getStatus().add(StatusType.RESERVED); } else if (owner == TaskOwnerEnum.group) { request.getStatus().add(StatusType.CREATED); request.getStatus().add(StatusType.READY); } return request; } /** * @see org.overlord.dtgov.ui.server.services.tasks.ITaskClient#setLocale(java.util.Locale) */ @Override public void setLocale(Locale locale) { client.setLocale(locale); } }