Package org.kie.remote.services.rest

Source Code of org.kie.remote.services.rest.ResourceBase

package org.kie.remote.services.rest;

import static org.kie.remote.common.rest.RestEasy960Util.defaultVariant;
import static org.kie.remote.common.rest.RestEasy960Util.getVariant;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Variant;

import org.jbpm.kie.services.impl.model.ProcessAssetDesc;
import org.jbpm.process.audit.AuditLogService;
import org.jbpm.services.api.model.ProcessDefinition;
import org.jbpm.services.task.commands.TaskCommand;
import org.jbpm.services.task.query.TaskSummaryImpl;
import org.kie.api.command.Command;
import org.kie.api.task.model.Group;
import org.kie.api.task.model.OrganizationalEntity;
import org.kie.api.task.model.Status;
import org.kie.api.task.model.User;
import org.kie.internal.task.api.TaskModelProvider;
import org.kie.internal.task.api.model.InternalOrganizationalEntity;
import org.kie.internal.task.api.model.InternalTask;
import org.kie.remote.services.AcceptedServerCommands;
import org.kie.remote.services.cdi.ProcessRequestBean;
import org.kie.remote.services.jaxb.JaxbCommandsRequest;
import org.kie.remote.services.jaxb.JaxbCommandsResponse;
import org.kie.remote.services.rest.exception.KieRemoteRestOperationException;
import org.kie.services.client.serialization.jaxb.impl.JaxbPaginatedList;
import org.kie.services.client.serialization.jaxb.impl.process.JaxbProcessDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ResourceBase {

    protected static final Logger logger = LoggerFactory.getLogger(ResourceBase.class);
  
    @Inject
    protected ProcessRequestBean processRequestBean;
   
    @Context
    private UriInfo uriInfo;
   
    @Context
    private HttpServletRequest httpRequest;

    /**
     * In order to be able to inject a mock instance for tests.
     * @param processRequestBean
     */
    public void setProcessRequestBean( ProcessRequestBean processRequestBean ) {
        this.processRequestBean = processRequestBean;
    }
   
     /**
      * In order to be able to inject a mock instance for tests.
      * @param uriInfo
      */
    void setUriInfo(UriInfo uriInfo) {
        this.uriInfo = uriInfo;
    }
  
    /**
     * In order to be able to inject a mock instance for tests.
     * @param httpRequest
     */
    void setHttpServletRequest(HttpServletRequest httpRequest) {
        this.httpRequest = httpRequest;
    }
   
    // Any query parameters used in REST calls (besides the query operations), should be added here
   
    static String PAGE_LONG_PARAM = "page";
    static String PAGE_SHORT_PARAM = "p";
    static String SIZE_LONG_PARAM = "pagesize";
    static String SIZE_SHORT_PARAM = "s";
  
    public static Set<String> paginationParams = new HashSet<String>();
    static {
        paginationParams.add(PAGE_LONG_PARAM);
        paginationParams.add(PAGE_SHORT_PARAM);
        paginationParams.add(SIZE_LONG_PARAM);
        paginationParams.add(SIZE_SHORT_PARAM);
    };
   
    public static final String PROC_INST_ID_PARAM_NAME = "runtimeProcInstId";
   
    public AuditLogService getAuditLogService() {
        return processRequestBean.getAuditLogService();
    }
   
    // execute --------------------------------------------------------------------------------------------------------------------
   
    @SuppressWarnings("rawtypes")
    protected JaxbCommandsResponse restProcessJaxbCommandsRequest(JaxbCommandsRequest request) {
        // If exceptions are happening here, then there is something REALLY wrong and they should be thrown.
        JaxbCommandsResponse jaxbResponse = new JaxbCommandsResponse(request);
        List<Command> commands = request.getCommands();

        if (commands != null) {
            int cmdListSize = commands.size();
          
            // First check to make sure that all commands will be processed
            for (int i = 0; i < cmdListSize; ++i) {
                Command<?> cmd = commands.get(i);
                if (!AcceptedServerCommands.isAcceptedCommandClass(cmd.getClass()) ) {
                    throw KieRemoteRestOperationException.forbidden("The execute REST operation does not accept " + cmd.getClass().getName() + " instances.");
                }
            }
          
            // Execute commands
            for (int i = 0; i < cmdListSize; ++i) {
                Command<?> cmd = commands.get(i);
                processRequestBean.processCommand(cmd, request, i, jaxbResponse);
            }
        }

        if (commands == null || commands.isEmpty()) {
            logger.info("Commands request object with no commands sent!");
        }

        return jaxbResponse;
    }
   
    // JSON / JAXB ---------------------------------------------------------------------------------------------------------------
   
    protected static Response createCorrectVariant(Object responseObj, HttpHeaders headers) {
        return createCorrectVariant(responseObj, headers, null);
    }
   
    protected static Response createCorrectVariant(Object responseObj, HttpHeaders headers, javax.ws.rs.core.Response.Status status) {
        ResponseBuilder responseBuilder = null;
        Variant v = getVariant(headers);
        if( v == null ) {
            v = defaultVariant;
        }
        if( status != null ) {
            responseBuilder = Response.status(status).entity(responseObj).variant(v);
        } else {
            responseBuilder = Response.ok(responseObj, v);
        }
        return responseBuilder.build();
    }
   

    // Request Params -------------------------------------------------------------------------------------------------------------
   
    protected Map<String, String[]> getRequestParams() {
        return httpRequest.getParameterMap();
    }

    protected static String getStringParam(String paramName, boolean required, Map<String, String[]> params, String operation) {
        String [] paramValues = getStringListParam(paramName, required, params, operation);
        if( ! required && (paramValues.length == 0) ) {
            return null;
        }
        if (paramValues.length != 1) {
            throw KieRemoteRestOperationException.badRequest("One and only one '" + paramName + "' query parameter required for '" + operation
                    + "' operation (" + paramValues.length + " passed).");
        }
        return paramValues[0];
    }

    private static final String [] EMPTY_STRING_ARR = new String[0];
   
    protected static List<String> getStringListParamAsList(String paramName, boolean required, Map<String, String[]> params, String operation) {
        String [] strList = getStringListParam(paramName, required, params, operation);
        if( strList.length == 0 ) {
            return Collections.EMPTY_LIST;
        }
        return Arrays.asList(strList);
    }
   
    protected static String[] getStringListParam(String paramName, boolean required, Map<String, String[]> params, String operation) {
        String[] paramValues = null;
        for (Entry<String, String[]> entry : params.entrySet()) {
            if (entry.getKey().equalsIgnoreCase(paramName)) {
                paramValues = entry.getValue();
                break;
            }
        }
        if (paramValues == null) {
            if (required) {
                throw KieRemoteRestOperationException.badRequest("Query parameter '" + paramName + "' required for '" + operation
                        + "' operation.");
            }
            return EMPTY_STRING_ARR;
        }
        return paramValues;
    }

   
    protected static Object getObjectParam(String paramName, boolean required, Map<String, String[]> params, String operation) {
        String paramVal = getStringParam(paramName, required, params, operation);
        if (!required && paramVal == null) {
            return null;
        }
        return getObjectFromString(paramName, paramVal);

    }

    protected static List<Long> getLongListParam(String paramName, boolean required, Map<String, String[]> params, String operation,
            boolean mustBeLong) {
        String [] paramValues = getStringListParam(paramName, required, params, operation);
        List<Long> longValues = new ArrayList<Long>();
        for( String strVal : paramValues ) {
           longValues.add((Long) getNumberFromString(paramName, strVal, mustBeLong));
        }
        return longValues;
    }
   
    protected static Number getNumberParam(String paramName, boolean required, Map<String, String[]> params, String operation,
            boolean mustBeLong) {
        String paramVal = getStringParam(paramName, required, params, operation);
        if (!required && paramVal == null) {
            return null;
        }
        return getNumberFromString(paramName, paramVal, mustBeLong);
    }

    private static Object getObjectFromString(String key, String mapVal) {
        if (mapVal.matches("^\".*\"$")) {
            return mapVal.substring(1, mapVal.length()-1);
        } else if (!mapVal.matches("^\\d+[li]?$")) {
            return mapVal;
        } else {
            return getNumberFromString(key, mapVal, false);
        }
    }

    /**
     * Returns a Long if no suffix is present.
     * Otherwise, possible suffixes are:
     * <ul>
     * <li>i : returns an Integer</li>
     * <li>l : returns an Long</li>
     * </ul>
     *
     * @param paramName
     * @param paramVal
     * @return
     */
    private static Number getNumberFromString(String paramName, String paramVal, boolean mustBeLong) {
        if (paramVal.matches("^\\d+[li]?$")) {
            if (paramVal.matches(".*i$")) {
                if (mustBeLong) {
                    throw KieRemoteRestOperationException.badRequest( paramName
                            + " parameter is numerical but contains the \"Integer\" suffix 'i' and must have no suffix or \"Long\" suffix 'l' ("
                            + paramVal + ")");
                }
                paramVal = paramVal.substring(0, paramVal.length() - 1);
                if (paramVal.length() > 9) {
                    throw KieRemoteRestOperationException.badRequest(paramName + " parameter is numerical but too large to be an integer ("
                            + paramVal + "i)");
                }
                return Integer.parseInt(paramVal);
            } else {
                if (paramVal.length() > 18) {
                    throw KieRemoteRestOperationException.badRequest(paramName + " parameter is numerical but too large to be a long ("
                            + paramVal + ")");
                }
                if (paramVal.matches(".*l$")) {
                    paramVal = paramVal.substring(0, paramVal.length() - 1);
                }
                return Long.parseLong(paramVal);
            }
        }
        throw KieRemoteRestOperationException.badRequest(paramName + " parameter does not have a numerical format (" + paramVal + ")");
    }

    protected static Map<String, Object> extractMapFromParams(Map<String, String[]> params, String operation) {
        Map<String, Object> map = new HashMap<String, Object>();

        for (Entry<String, String[]> entry : params.entrySet()) {
            if (entry.getKey().startsWith("map_")) {
                String key = entry.getKey();
                String[] paramValues = entry.getValue();
                if (paramValues.length != 1) {
                    throw KieRemoteRestOperationException.badRequest("Only one map_* (" + key + ") query parameter allowed for '" + operation
                            + "' operation (" + paramValues.length + " passed).");
                }
                String mapKey = key.substring("map_".length());
                String mapVal = paramValues[0].trim();

                map.put(mapKey, getObjectFromString(key, mapVal));
            }
        }
        return map;
    }

    protected static List<OrganizationalEntity> getOrganizationalEntityListFromParams(Map<String, String[]> params, boolean required, String operation) {
        List<OrganizationalEntity> orgEntList = new ArrayList<OrganizationalEntity>();

        String [] users = getStringListParam("user", false, params, operation);
        String [] groups = getStringListParam("group", false, params, operation);
        if (required && (users.length == 0) && (groups.length == 0)) {
            throw KieRemoteRestOperationException.badRequest("At least 1 query parameter (either 'user' or 'group') is required for the '" + operation + "' operation.");
        }
       
        for( String user : users ) {
            User newuser = TaskModelProvider.getFactory().newUser();
            ((InternalOrganizationalEntity) newuser).setId(user);
            orgEntList.add(newuser);
        }
        for( String group : groups ) {
            Group newuser = TaskModelProvider.getFactory().newGroup();
            ((InternalOrganizationalEntity) newuser).setId(group);
            orgEntList.add(newuser);
        }
       
        return orgEntList;
    }
   
    protected static TaskSummaryImpl convertTaskToTaskSummary(InternalTask task) {
       TaskSummaryImpl taskSummary = new TaskSummaryImpl(
               task.getId().longValue(),
               task.getNames().get(0).getText(),
               task.getSubjects().get(0).getText(),
               task.getDescriptions().get(0).getText(),
               task.getTaskData().getStatus(),
               task.getPriority(),
               task.getTaskData().isSkipable(),
               task.getTaskData().getActualOwner(),
               task.getTaskData().getCreatedBy(),
               task.getTaskData().getCreatedOn(),
               task.getTaskData().getActivationTime(),
               task.getTaskData().getExpirationTime(),
               task.getTaskData().getProcessId(),
               task.getTaskData().getProcessSessionId(),
               task.getTaskData().getProcessInstanceId(),
               task.getTaskData().getDeploymentId(),
               task.getSubTaskStrategy(),
               task.getTaskData().getParentId()
               );
       return taskSummary;
    }
   
    protected static List<Status> convertStringListToStatusList( List<String> statusStrList ) {
        List<Status> statuses = null;
        if( statusStrList != null && ! statusStrList.isEmpty() ) {
            statuses = new ArrayList<Status>();
            for( String statusStr : statusStrList ) {
                try {
                    statuses.add(getEnum(statusStr));
                } catch(IllegalArgumentException iae) {
                    throw KieRemoteRestOperationException.badRequest(statusStr + " is not a valid status type for a task." );
                }
            }
        }
        return statuses;
    }
   
    // Pagination ----------------------------------------------------------------------------------------------------------------
   
    static int PAGE_NUM = 0;
    static int PAGE_SIZE = 1;
  
    protected static int [] getPageNumAndPageSize(Map<String, String[]> params, String oper) {
        int [] pageInfo = new int[2];
       
        int p = 0;
        Number page = getNumberParam(PAGE_LONG_PARAM, false, params, oper, false);
        if( page != null ) {
            p = page.intValue();
        } else {
            Number pageShort = getNumberParam(PAGE_SHORT_PARAM, false, params, oper, false);
            if( pageShort != null ) {
                p = pageShort.intValue();
            }
        }
        if( p < 0 ) {
            p = 0;
        }
       
        int s = 0;
        Number pageSize = getNumberParam(SIZE_LONG_PARAM, false, params, oper, false);
        if( pageSize != null ) {
            s = pageSize.intValue();
        } else {
            Number pageSizeShort = getNumberParam(SIZE_SHORT_PARAM, false, params, oper, false);
            if( pageSizeShort != null ) {
                s = pageSizeShort.intValue();
            }
        }
        if( s < 0 ) {
            s = 0;
        }
       
        pageInfo[PAGE_NUM] = p;
        pageInfo[PAGE_SIZE] = s;
       
        return pageInfo;
    }
  
    protected static <T> List<T> paginate(int[] pageInfo, List<T> results) {
        List<T> pagedResults = new ArrayList<T>();
        assert pageInfo[0] >= 0;
        if( pageInfo[1] > 0 && pageInfo[0] == 0 ) {
            pageInfo[0] = 1;
        }
        if( pageInfo[0] == 0 && pageInfo[1] == 0) {
            return results;
        else if( pageInfo[0] > 0 ) {
            // for( i  = start of page; i < start of next page && i < num results; ++i )
            for( int i = (pageInfo[0]-1)*pageInfo[1]; i < pageInfo[0]*pageInfo[1] && i < results.size(); ++i ) {
                pagedResults.add(results.get(i));
            }
        }
        return pagedResults;
    }
   
    protected static int getMaxNumResultsNeeded(int [] pageInfo) {
        int numResults = pageInfo[PAGE_NUM]*pageInfo[PAGE_SIZE];
        if( numResults == 0 ) {
            numResults = 1000;
        }
        return numResults;
    }
  
    protected static <T, R extends JaxbPaginatedList<T>> R
        paginateAndCreateResult(Map<String, String[]> params, String oper, List<T> results, R resultList) {
       
        // paginate
        int [] pageInfo = getPageNumAndPageSize(params, oper);
        return paginateAndCreateResult(pageInfo, results, resultList);
    }
       
    protected static <T, R extends JaxbPaginatedList<T>> R
        paginateAndCreateResult(int [] pageInfo, List<T> results, R resultList) {
       
        if( pageInfo[0] == 0 && pageInfo[1] == 0 ) {
            // no pagination
            resultList.addContents(results);
            return resultList;
        }
       
        results = paginate(pageInfo, results);
      
        // create result
        resultList.addContents(results);
        resultList.setPageNumber(pageInfo[PAGE_NUM]);
        resultList.setPageSize(pageInfo[PAGE_SIZE]);
       
        return resultList;
    }
    // URL/Context helper methods -------------------------------------------------------------------------------------------------
   
    protected String getBaseUri() {
        return uriInfo.getBaseUri().toString();
    }
   
    protected String getRequestUri() {
        return httpRequest.getRequestURI();
    }
   
    protected String getRelativePath() {
        String url =  httpRequest.getRequestURI();
        url.replaceAll( ".*/rest", "");
        return url;
    }
   
    // Other helper methods ------------------------------------------------------------------------------------------------------
   
    protected static Status getEnum(String value) {
        value = value.substring(0,1).toUpperCase() + value.substring(1).toLowerCase();

        try {
            return Status.valueOf(value);
        } catch( IllegalArgumentException iae ) {
           if( value.equalsIgnoreCase("inprogress") )  {
               return Status.InProgress;
           }
           throw iae;
        }
    }
 
    protected JaxbProcessDefinition convertProcAssetDescToJaxbProcDef(ProcessDefinition procAssetDesc) {
        JaxbProcessDefinition jaxbProcDef = new JaxbProcessDefinition();
        jaxbProcDef.setDeploymentId(((ProcessAssetDesc)procAssetDesc).getDeploymentId());
        jaxbProcDef.setForms(((ProcessAssetDesc)procAssetDesc).getForms());
        jaxbProcDef.setId(procAssetDesc.getId());
        jaxbProcDef.setName(procAssetDesc.getName());
        jaxbProcDef.setPackageName(procAssetDesc.getPackageName());
        jaxbProcDef.setVersion(procAssetDesc.getVersion());
       
        return jaxbProcDef;
    }
    // TODO: shouldn't this also take a process runtime id for per-process runtimes?
    public <T> T doRestTaskOperation(TaskCommand<T> cmd) {
        return processRequestBean.doRestTaskOperation(null, null, null, null, cmd);
    }
   
    protected <T> T doRestTaskOperationWithTaskId(Long taskId, TaskCommand<T> cmd) {
        return processRequestBean.doRestTaskOperation(taskId, null, null, null, cmd);
    }
   
    protected <T> T doRestTaskOperationWithDeploymentId(String deploymentId, TaskCommand<T> cmd) {
        return processRequestBean.doRestTaskOperation(null, deploymentId, null, null, cmd);
    }
}
TOP

Related Classes of org.kie.remote.services.rest.ResourceBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.