diff --git a/RestAPIContext.docx b/RestAPIContext.docx index 30f398e..0a51f8c 100644 Binary files a/RestAPIContext.docx and b/RestAPIContext.docx differ diff --git a/RestAPIContext.pdf b/RestAPIContext.pdf index 8fb886f..393e4dd 100644 Binary files a/RestAPIContext.pdf and b/RestAPIContext.pdf differ diff --git a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextCaseId.groovy b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextCaseId.groovy index 9bbbc94..f5527bb 100644 --- a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextCaseId.groovy +++ b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextCaseId.groovy @@ -1,5 +1,4 @@ package org.bonitasoft.rest.context -// package org.bonitasoft.rest.context; import java.sql.Connection; import java.sql.ResultSet; @@ -100,6 +99,8 @@ public class RestContextCaseId { public Long documentId=null; public Document document=null; + + // different item loaded public ProcessDefinition processDefinition=null; @@ -107,7 +108,13 @@ public class RestContextCaseId { public ActivityInstance activityInstance = null; public ArchivedProcessInstance archivedProcessInstance = null; public ArchivedActivityInstance archivedActivityInstance=null; - + + /** + * when we have a callmap, the task may be a task in the subprocess. In this moment, the scope may be use to decide were the value has to be retrieve. + * We save the local information processInstanceParent (of the task) and the processInstanceRoot + */ + ProcessInstance processInstanceParent = null; + ProcessInstance processInstanceRoot = null; /** @@ -118,6 +125,16 @@ public class RestContextCaseId { }; TypeUrl detectTypeUrl = TypeUrl.UNKNOW; + + /* + * specify the scope of the case to search. + * - DEFAULT : if this is a caseId, then result is the caseId given. A task ? caseId= case( task ) so maybe the subCaseId + * - ROOT : the caseId is force to the root parent + */ + public enum ScopeSearch { ROOT, DEFAULT}; + public ScopeSearch scopeSearch = ScopeSearch.DEFAULT; + + Long userId = null; ProcessAPI processAPI; @@ -305,7 +322,22 @@ public class RestContextCaseId { contextResult.put("username", user.getUserName()); contextResult.put("processdefinitionid", processDefinitionId) contextResult.put("taskid", taskInstanceId) - contextResult.put("caseid", processInstanceId); + + // Ok, here a special situation: + // if processInstanceRoot !=null, then we : + // use the root as caseId (because this is the caseId for the final user) + // parentroot is given too, and the processInstance is display too because this is the one use to display the variable + if (processInstanceRoot !=null) + { + if (processInstanceRoot != null) + contextResult.put("caseid", processInstanceRoot.getId()); + if (processInstanceParent!=null) + contextResult.put("caseidparent", processInstanceParent.getId()); + + contextResult.put("caseiduse", processInstanceId); + } + else + contextResult.put("caseid", processInstanceId); if (activityInstance!=null) { contextResult.put("taskname", activityInstance.getName()); contextResult.put("isTaskArchived", false ); @@ -341,7 +373,6 @@ public class RestContextCaseId { if (posEqual!=-1) this.parametersMap.put( paramAndValue.substring(0,posEqual), paramAndValue.substring(posEqual+1)); } - this.pametersRequest = null; this.restConfiguration = null; internalDecodeParameters(); } @@ -384,7 +415,7 @@ public class RestContextCaseId { public String getAnalysisString() { return analysisString; } ; - + /** * main part : the contextCaseid get all informations from the url */ @@ -435,7 +466,13 @@ public class RestContextCaseId { catch(Exception e) { analysisString+= "a Boolean is expected for the parameters log ["+getOneParameter("log")+"]"; } - + if (getOneParameter("scope")!=null) + { + if (ScopeSearch.ROOT.toString().equals( getOneParameter("scope"))) + scopeSearch=ScopeSearch.ROOT; + if (ScopeSearch.DEFAULT.toString().equals( getOneParameter("scope"))) + scopeSearch=ScopeSearch.DEFAULT; + } if ( (detectTypeUrl == TypeUrl.TASKEXECUTION) || (detectTypeUrl == TypeUrl.UNKNOW)) taskInstanceIdParam = getOneParameterLong("taskId", "Error with taskId"); @@ -447,7 +484,7 @@ public class RestContextCaseId { { initializeFromContentStorageId( contentStorageId ); analysisString +=";docId["+documentId+"] processInstanceId["+processInstanceId+"]"; - caseInstanceIdParam= (document==null ? null : document.getId()); + caseInstanceIdParam= (document==null ? null : document.getProcessInstanceId()); } if ( (detectTypeUrl == TypeUrl.PROCESSINSTANCIATION) || (detectTypeUrl == TypeUrl.UNKNOW)) @@ -461,7 +498,20 @@ public class RestContextCaseId { { activityInstance = processAPI.getActivityInstance( taskInstanceIdParam ); taskInstanceId = activityInstance.getId(); - caseInstanceIdParam = activityInstance.getParentContainerId(); + // 2 possibiluty ; the getParentContainerId display the local parent, where getRootContainerId display the root caseId + // in case of a subprocess, this is a main difference : variable are not the same ! Actor filter too are different + Long parentCaseId= activityInstance.getParentContainerId(); + Long rootCaseId = activityInstance.getRootContainerId(); + if (parentCaseId != rootCaseId) + { + processInstanceParent = processAPI.getProcessInstance( parentCaseId ); + processInstanceRoot = processAPI.getProcessInstance( rootCaseId ); + + } + if (scopeSearch == ScopeSearch.DEFAULT) + caseInstanceIdParam = parentCaseId; + if (scopeSearch == ScopeSearch.ROOT) + caseInstanceIdParam = rootCaseId; } } catch(Exception e ) { @@ -487,11 +537,13 @@ public class RestContextCaseId { { processInstance = processAPI.getProcessInstance( caseInstanceIdParam ); processInstanceId = processInstance.getId(); + processDefinitionIdParam = processInstance.getProcessDefinitionId(); } } catch(Exception e ) { // maybe normal : it's archived ? + analysisString+="Error with caseInstanceId["+caseInstanceIdParam+"] : "+e.toString(); }; try { @@ -505,6 +557,15 @@ public class RestContextCaseId { { analysisString+="Error with caseId["+caseInstanceIdParam+"] : "+e.toString(); }; + // root process instance ? + if (processInstance!=null) + try + { + processInstanceRoot= processAPI.getProcessInstance( processInstance.getRootProcessInstanceId() ); + } catch(Exception e ) + { + analysisString+="No processRoot["+processInstance.getRootProcessInstanceId()+"] : "+e.toString(); + }; // --------------------------------- processAPI try @@ -545,7 +606,7 @@ public class RestContextCaseId { // now read the defautl date format String defaultDateFormatSt = getOneParameter("dateformat"); - if (defaultDateFormatSt== null || defaultDateFormatSt.trim().length==0) + if (defaultDateFormatSt== null || defaultDateFormatSt.trim().length()==0) { // thanks to KilianStein to propose this configuration way defaultDateFormatSt =restConfiguration==null ? null : restConfiguration.getDefaultDateFormat(); @@ -637,7 +698,7 @@ public class RestContextCaseId { con.close(); } if (documentId!=null) { - document = processAPI.getDocument(documentId); + document = processAPI.getDocument(documentId); } return allIsOk; } diff --git a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextHandleGet.groovy b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextHandleGet.groovy index e55600b..2ce6c38 100644 --- a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextHandleGet.groovy +++ b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextHandleGet.groovy @@ -64,34 +64,6 @@ class RestContextHandleGet implements RestApiController { - /* -------------------------------------------------------------------------------- */ - /* */ - /* class PerformanceTrace */ - /* */ - /* -------------------------------------------------------------------------------- */ - public static class PerformanceTrace { - private List> listOperations = new ArrayList>(); - public void addMarker(String operation) { - long currentTime= System.currentTimeMillis(); - Map oneOperation = new HashMap(); - oneOperation.put("t",System.currentTimeMillis()); - oneOperation.putAt("n",operation); - listOperations.add( oneOperation ); - } - - public String trace() { - String result=""; - for (int i=1;i map, String indentation, RestContextCaseId contextCaseId) + { + for (String key: map.keySet()) + { + Object value=map.get( key ); + if (value instanceof Map) + { + contextCaseId.log( indentation+"["+key+"] = MAP"); + traceResult( (Map) value, indentation+" ", contextCaseId); + } + else + contextCaseId.log( indentation+"["+key+"] = ["+ (value==null ? "null": value.getClass().getName()+"/"+value) +"]"); + + } + } /** * get the content of the REST API * @param contextCaseId @@ -272,7 +276,7 @@ class RestContextHandleGet implements RestApiController { */ private void getContent( Map rootResult, RestContextCaseId contextCaseId, - PerformanceTrace performanceTrace2, + RestContextTrackPerformance trackPerformance, APIClient apiClient) { // get the list of all Business Data @@ -286,7 +290,10 @@ class RestContextHandleGet implements RestApiController { { contextCaseId.log( "Collect BusinessData from: processinstanceid["+contextCaseId.processInstanceId+"]"); + Map trackSubOperation = trackPerformance.startSubOperation("getProcessBusinessDataReferences"); List tempList = businessDataAPI.getProcessBusinessDataReferences(contextCaseId.processInstanceId, 0,1000); + trackPerformance.endSubOperation( trackSubOperation); + if (tempList!=null) { contextCaseId.log( "Collect BusinessData from: processinstanceid["+tempList.size()+"]"); @@ -300,7 +307,10 @@ class RestContextHandleGet implements RestApiController { { // logger.info(">>> *BEGIN* ArchivedProcessInstanceExecutionContext<<"); + Map trackSubOperation = trackPerformance.startSubOperation("getArchivedProcessInstanceExecutionContext"); Map map = processAPI.getArchivedProcessInstanceExecutionContext(contextCaseId.archivedProcessInstance.getId()); + trackPerformance.endSubOperation( trackSubOperation); + for (String key : map.keySet() ) { if (map.get( key ) instanceof BusinessDataReference) @@ -313,8 +323,10 @@ class RestContextHandleGet implements RestApiController { } contextCaseId.log( "Collect BusinessData from: getArchivedProcessInstanceExecutionContext :archivedProcessInstance.getId() ["+listBusinessData.size()+"]"); // logger.info(">>> *END* ArchivedProcessInstanceExecutionContext<<"); - + trackSubOperation = trackPerformance.startSubOperation("getProcessBusinessDataReferences archivedSOURCEProcessInstance["+contextCaseId.archivedProcessInstance.getSourceObjectId()+"]"); List tempList = businessDataAPI.getProcessBusinessDataReferences(contextCaseId.archivedProcessInstance.getSourceObjectId(), 0,1000); + trackPerformance.endSubOperation( trackSubOperation); + if (tempList!=null) { contextCaseId.log( "Collect BusinessData from: archivedActivityInstance.getSourceObjectId() ["+tempList.size()+"]"); @@ -322,7 +334,9 @@ class RestContextHandleGet implements RestApiController { listBusinessData.put( bde.getName(), bde ); } + trackSubOperation = trackPerformance.startSubOperation("getProcessBusinessDataReferences archiveProcessInstance["+contextCaseId.archivedProcessInstance.getId()+"]"); tempList = businessDataAPI.getProcessBusinessDataReferences(contextCaseId.archivedProcessInstance.getId(), 0,1000); + trackPerformance.endSubOperation( trackSubOperation); if (tempList!=null) { contextCaseId.log( "Collect BusinessData from: archivedActivityInstance.getId() ["+tempList.size()+"]"); @@ -330,7 +344,7 @@ class RestContextHandleGet implements RestApiController { listBusinessData.put( bde.getName(), bde ); } } - performanceTrace2.addMarker("collectListBusinessData"); + trackPerformance.addMarker("collectListBusinessData"); // now, process the list @@ -348,48 +362,62 @@ class RestContextHandleGet implements RestApiController { if (contextCaseId.processInstance!=null) { instanceForBdm = contextCaseId.processInstance.getId(); + Map trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstances"); List listDataInstance = processAPI.getProcessDataInstances(contextCaseId.processInstance.getId(), 0,1000); + trackPerformance.endSubOperation( trackSubOperation); + for (DataInstance data : listDataInstance) { contextCaseId.log( "************************** DataInstance detected ["+data.getName()+"]"); - completeValueProcessVariable( rootResult, data.getName(), varAction, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap() ); + completeValueProcessVariable( rootResult, data.getName(), varAction, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap(), trackPerformance ); } - performanceTrace2.addMarker("getAllProcessData"); + trackPerformance.addMarker("getAllProcessData"); } if (contextCaseId.activityInstance!=null) { + Map trackSubOperation = trackPerformance.startSubOperation("getActivityDataInstances"); List listDataInstance = processAPI.getActivityDataInstances(contextCaseId.activityInstance.getId(), 0,1000); + trackPerformance.endSubOperation( trackSubOperation); + for (DataInstance data : listDataInstance) { - contextCaseId.log( "************************** LocalDataInstance detected ["+data.getName()+"]"); - completeValueProcessVariable(rootResult, data.getName(), varAction, contextCaseId, apiClient,contextCaseId.getPilot().getPilotDataMap() ); + contextCaseId.log( "************************** LocalDataInstance detected ["+data.getName()+"] contentType["+data.getContainerType()+"]"); + if (! "PROCESS_INSTANCE".equals( data.getContainerType() )) + completeValueProcessVariable(rootResult, data.getName(), varAction, contextCaseId, apiClient,contextCaseId.getPilot().getPilotDataMap(), trackPerformance ); } - performanceTrace2.addMarker("getAllActivityData"); + trackPerformance.addMarker("getAllActivityData"); } // ----- archived part if (contextCaseId.archivedProcessInstance!=null) { instanceForBdm = contextCaseId.archivedProcessInstance.getId(); + Map trackSubOperation = trackPerformance.startSubOperation("getArchivedProcessDataInstances"); List listDataInstance = processAPI.getArchivedProcessDataInstances(contextCaseId.archivedProcessInstance.getSourceObjectId(), 0,1000); + trackPerformance.endSubOperation( trackSubOperation); + for (ArchivedDataInstance data : listDataInstance) { - contextCaseId.log( "************************** ArchivedDataInstance detected ["+data.getName()+"]"); - completeValueProcessVariable( rootResult, data.getName(), varAction, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap() ); + contextCaseId.log( "************************** ArchivedDataInstance detected ["+data.getName()+"] contentType["+data.getContainerType()+"]"); + if (! "PROCESS_INSTANCE".equals( data.getContainerType() )) + completeValueProcessVariable( rootResult, data.getName(), varAction, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap(), trackPerformance ); } - performanceTrace2.addMarker("getAllArchivedProcessData"); + trackPerformance.addMarker("getAllArchivedProcessData"); } if (contextCaseId.archivedActivityInstance!=null) { + Map trackSubOperation = trackPerformance.startSubOperation("getArchivedActivityDataInstances"); List listDataInstance = processAPI.getArchivedActivityDataInstances(contextCaseId.archivedActivityInstance.getSourceObjectId(), 0,1000); + trackPerformance.endSubOperation( trackSubOperation); + for (ArchivedDataInstance data : listDataInstance) { contextCaseId.log( "************************** ArchivedActivityDataInstance detected ["+data.getName()+"]"); - completeValueProcessVariable( rootResult, data.getName(), varAction, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap() ); + completeValueProcessVariable( rootResult, data.getName(), varAction, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap(),trackPerformance ); } - performanceTrace2.addMarker("getAllArchivedActivityData"); + trackPerformance.addMarker("getAllArchivedActivityData"); } @@ -403,15 +431,18 @@ class RestContextHandleGet implements RestApiController { for (BusinessDataReference businessData : listBusinessData.values()) { contextCaseId.log( "Loop Get BDM["+businessData.getName()+"] / type["+businessData.getType()+"]"); - completeValueBdmData( rootResult, businessData, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap() ); + completeValueBdmData( rootResult, businessData, contextCaseId, apiClient, contextCaseId.getPilot().getPilotDataMap(),trackPerformance ); } - performanceTrace2.addMarker("getBusinessData"); + trackPerformance.addMarker("getBusinessData"); //--------------------- parameters contextCaseId.log( "Check parameters"); if (contextCaseId.processDefinitionId!=null) { + Map trackSubOperation = trackPerformance.startSubOperation("getParameterInstances"); List listParameters = processAPI.getParameterInstances(contextCaseId.processDefinitionId, 0, 100, ParameterCriterion.NAME_ASC); + trackPerformance.endSubOperation( trackSubOperation); + if (listParameters!=null) for (ParameterInstance parameter : listParameters) { @@ -445,15 +476,15 @@ class RestContextHandleGet implements RestApiController { { Map mapPilot = contextCaseId.getPilot().getPilotDataMap() ; - completeValueBdmData( rootResult, listBusinessData.get( varName ), contextCaseId, apiClient, mapPilot ); - performanceTrace2.addMarker("getBdmData["+varName+"]"); + completeValueBdmData( rootResult, listBusinessData.get( varName ), contextCaseId, apiClient, mapPilot, trackPerformance ); + trackPerformance.addMarker("getBdmData (completeValueBdmData) ["+varName+"]"); } else { Map mapPilot = contextCaseId.getPilot().getPilotDataMap() ; - completeValueProcessVariable( rootResult, varName, varAction, contextCaseId, apiClient, mapPilot ); - performanceTrace2.addMarker("getData["+varName+"]"); + completeValueProcessVariable( rootResult, varName, varAction, contextCaseId, apiClient, mapPilot, trackPerformance ); + trackPerformance.addMarker("getData (completeValueProcessVariable)["+varName+"]"); } @@ -481,8 +512,9 @@ class RestContextHandleGet implements RestApiController { if (contextCaseId.processInstanceId!=null) { + Map trackSubOperation = trackPerformance.startSubOperation("getLastVersionOfDocuments"); List listDocuments = processAPI.getLastVersionOfDocuments(contextCaseId.processInstanceId, 0,100, DocumentCriterion.NAME_ASC); - + trackPerformance.endSubOperation( trackSubOperation); for (Document oneDoc : listDocuments) { @@ -534,6 +566,7 @@ class RestContextHandleGet implements RestApiController { } else if (contextCaseId.processDefinitionId !=null) { // detect all document and create some empty variable + Map trackSubOperation = trackPerformance.startSubOperation("detectDocument"); DesignProcessDefinition designProcessDefinition = processAPI.getDesignProcessDefinition( contextCaseId.processDefinitionId ); FlowElementContainerDefinition flowElementContainerDefinition = designProcessDefinition.getFlowElementContainer(); List listDocumentDefinition = flowElementContainerDefinition.getDocumentDefinitions(); @@ -544,6 +577,8 @@ class RestContextHandleGet implements RestApiController { for (DocumentListDefinition documentListDefinition : listDocumentListDefinition ) rootResult.put( documentListDefinition.getName(), new ArrayList()); + trackPerformance.endSubOperation( trackSubOperation); + } } @@ -612,7 +647,8 @@ class RestContextHandleGet implements RestApiController { String varAction, RestContextCaseId contextCaseId, APIClient apiClient, - Map pilotDataMap) + Map pilotDataMap, + RestContextTrackPerformance trackPerformance) { ProcessAPI processAPI = apiClient.processAPI; @@ -625,10 +661,15 @@ class RestContextHandleGet implements RestApiController { if (contextCaseId.processInstance != null) try { + Map trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / getProcessData"); DataInstance dataInstance = processAPI.getProcessDataInstance(varName.toString(), contextCaseId.processInstance.getId() ); + trackPerformance.endSubOperation( trackSubOperation); + contextCaseId.log( "completeValueProcessVariable: Get variable["+varName+"] is a PROCESSDATA.a : ["+dataInstance.getValue()+"] class["+dataInstance.getClassName()+"]"); - restContextTransformData.transform( rootResult, "", dataInstance.getName(), dataInstance.getValue(), pilotDataMap,0); + trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / transform"); + restContextTransformData.transform( rootResult, dataInstance.getName(), dataInstance.getName(), dataInstance.getValue(), pilotDataMap,0); + trackPerformance.endSubOperation( trackSubOperation); return; } catch (DataNotFoundException dnte) {}; @@ -637,9 +678,14 @@ class RestContextHandleGet implements RestApiController { try { // logger.info("Try get localvariable["+varName+"]"); + Map trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / getActivityData"); DataInstance dataInstance = processAPI.getActivityDataInstance(varName.toString(), contextCaseId.activityInstance.getId() ); + trackPerformance.endSubOperation( trackSubOperation); + contextCaseId.log( "completeValueProcessVariable: Get variable["+varName+"] is a ACTIVITYDATA: ["+dataInstance.getValue()+"] class["+dataInstance.getClassName()+"]"); - restContextTransformData.transform( rootResult, "", dataInstance.getName(), dataInstance.getValue(), pilotDataMap,0 ); + trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / transform"); + restContextTransformData.transform( rootResult, dataInstance.getName(), dataInstance.getName(), dataInstance.getValue(), pilotDataMap,0 ); + trackPerformance.endSubOperation( trackSubOperation); return; } catch (DataNotFoundException dnte) {}; @@ -647,10 +693,15 @@ class RestContextHandleGet implements RestApiController { try { contextCaseId.log( "completeValueProcessVariable: search variable["+varName+"] in getArchivedProcessDataInstance"); + Map trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / getrchivedProcessData"); ArchivedDataInstance archivedDataInstance = processAPI.getArchivedProcessDataInstance (varName.toString(), contextCaseId.archivedProcessInstance.getSourceObjectId() ); + trackPerformance.endSubOperation( trackSubOperation); + contextCaseId.log( "completeValueProcessVariable: Get variable["+varName+"] is a ARCHIVEDPROCESSDATA : ["+archivedDataInstance.getValue()+"] class["+archivedDataInstance.getClassName()+"]"); - restContextTransformData.transform( rootResult, "", archivedDataInstance.getName(), archivedDataInstance.getValue(), pilotDataMap,0 ); + trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / transform"); + restContextTransformData.transform( rootResult, archivedDataInstance.getName(), archivedDataInstance.getName(), archivedDataInstance.getValue(), pilotDataMap,0 ); + trackPerformance.endSubOperation( trackSubOperation); return; } catch (ArchivedDataNotFoundException dnte) {}; @@ -660,10 +711,14 @@ class RestContextHandleGet implements RestApiController { try { contextCaseId.log( "completeValueProcessVariable: search variable["+varName+"] in getArchivedActivityDataInstance"); + Map trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / getArchivedActivityProcessData"); ArchivedDataInstance archivedDataInstance = processAPI. getArchivedActivityDataInstance( varName.toString(), contextCaseId.archivedActivityInstance.getSourceObjectId() ); + trackPerformance.endSubOperation( trackSubOperation); contextCaseId.log( "completeValueProcessVariable: Get variable["+varName+"] is a ARCHIVEDPROCESSDATA : ["+archivedDataInstance.getValue()+"] class["+archivedDataInstance.getClassName()+"]"); - restContextTransformData.transform( rootResult,"", archivedDataInstance.getName(),archivedDataInstance.getValue(), pilotDataMap, 0); + trackSubOperation = trackPerformance.startSubOperation("getProcessDataInstance["+varName.toString()+"] / transform"); + restContextTransformData.transform( rootResult, archivedDataInstance.getName(), archivedDataInstance.getName(),archivedDataInstance.getValue(), pilotDataMap, 0); + trackPerformance.endSubOperation( trackSubOperation); return; } catch (ArchivedDataNotFoundException dnte) {}; } @@ -674,99 +729,7 @@ class RestContextHandleGet implements RestApiController { return; } - /** - * save the value in the rootResult. If the value is a Object - * @deprecated - * - private void completeValueFromDataDeprecated( Map rootResult, String varName, Object varValue, Map pilotDataMap, RestContextCaseId contextCaseId ) - { - if (pilotDataMap==null) - return; - Object pilotAction = pilotDataMap.get( varName ); - contextCaseId.log( "========================= completeValueFromData.begin: Get variable["+varName+"] action["+pilotAction+"] pilotAction["+pilotAction+"] pilotDataMap["+pilotDataMap+"] value["+varValue+"] "); - if (pilotAction instanceof Map) - { - contextCaseId.log( " completeValueFromData.: Action is MAP : "+pilotAction); - // attention, we may have at this point an object : it's time to transform it in MAP, LIST, ... - Object varValueTransformed = varValue; - if (varValueTransformed!= null) - if (! ( ( varValueTransformed instanceof Map) || (varValueTransformed instanceof List))) - { - contextCaseId.log( " completeValueFromData.: Transform the object to MAP : "+varValueTransformed); - String jsonSt = new JsonBuilder( varValueTransformed ).toPrettyString(); - varValueTransformed = new JsonSlurper().parseText(jsonSt); - contextCaseId.log( " completeValueFromData.: Transform the objecin MAP : "+varValueTransformed); - } - // we have a Map like { Attribut1: xxx} - if (varValueTransformed instanceof Map) - { - contextCaseId.log( " completeValueFromData.: Value is MAP : "+varValueTransformed); - Map subResult = new HashMap(); - rootResult.put(varName, subResult); - for (String key : pilotAction.keySet()) - { - contextCaseId.log( " completeValueFromData. recursiv call : key["+key+"] varValueTransformed.get( key )["+varValueTransformed.get( key )+"] pilotAction["+pilotAction+"]"); - if (pilotAction.get( key ) instanceof Map) - completeValueFromData( subResult, key, varValueTransformed.get( key ), pilotAction.get( key ), contextCaseId); - else - rootResult.put(varName, transformValue( varValueTransformed, pilotAction.get( key )==null ? null : pilotAction.get( key ).toString(), contextCaseId )); - } - } - else if (varValueTransformed instanceof List) - { - contextCaseId.log( " completeValueFromData.: Value is LIST : "+varValueTransformed); - // Ok, apply the action on each element of the list - List> subResult = new ArrayList>(); - rootResult.put(varName, subResult); - for (int i=0; i< ((List) varValueTransformed).size();i++) - { - Map subResultIterator = new HashMap(); - subResult.add(subResultIterator); - for (String key : pilotAction.keySet()) - { - completeValueFromData( subResultIterator, key, ((List) varValueTransformed).getAt( i ).get( key ), pilotAction.get( key ), contextCaseId); - } - } - } - else if (varValue == null) - { - rootResult.put(varName,null); - } - else - { - contextCaseId.log( " completeValueFromData.: Value is not a MAP and not a LIST do nothing : "+varValue.getClass().getName()); - // action is a MAP and the value is not... not, do nothing here - } - } // end of varcontext as a Map - else - { - contextCaseId.log( " completeValueFromData.: Direct transformation ("+(pilotAction==null ? "data" : pilotAction.toString())+")"); - rootResult.put(varName, transformValue( varValue, pilotAction==null ? "data" : pilotAction.toString(), contextCaseId) ); - if (contextCaseId.isLog) - { - contextCaseId.log( " completeValueFromData. Set in["+varName+"] : ["+rootResult.get(varName)+"]"); - if (rootResult.get(varName)!=null) - { - String jsonSt = new JsonBuilder( rootResult.get(varName) ).toPrettyString(); - // contextCaseId.log( " completeValueFromData. JSON="+jsonSt); - } - } - } - // special case for an enum - if (varValue instanceof Enum) - { - List listOptions = new ArrayList(); - // get the enummeration - Object[] options = ((Enum) varValue).values(); - for ( Object oneOption : options) - { - listOptions.add( oneOption.toString() ); - } - rootResult.put(varName+"_list", listOptions ); - } - contextCaseId.log( "========================= completeValueFromData.end: Get variable["+varName+"]"); - } - */ + /* -------------------------------------------------------------------------------- */ /* */ /* completeValueBdmData */ @@ -780,7 +743,8 @@ class RestContextHandleGet implements RestApiController { BusinessDataReference businessData, RestContextCaseId contextCaseId, APIClient apiClient, - Map pilotDataMap) + Map pilotDataMap, + RestContextTrackPerformance trackPerformance) { ProcessAPI processAPI = apiClient.processAPI; @@ -792,6 +756,7 @@ class RestContextHandleGet implements RestApiController { { // contextCaseId.log("completeValueBdmData.2: Get Business Reference ["+businessData.getName()+"]"); + Map trackSubOperation = null; // the result is maybe a HASHMAP or a LIST Object resultBdm = null; @@ -800,6 +765,7 @@ class RestContextHandleGet implements RestApiController { if (businessData instanceof MultipleBusinessDataReference) { // this is a multiple data + trackSubOperation = trackPerformance.startSubOperation("completeValueBdmData["+businessData.getName()+"] MULTIPLE/ storageId"); isMultiple=true; contextCaseId.log( "completeValueBdmData.3 Get MULTIPLE Business Reference ["+businessData.getName()+"] : type["+businessData.getType()+"]"); @@ -813,6 +779,8 @@ class RestContextHandleGet implements RestApiController { } if (businessData instanceof SimpleBusinessDataReference) { + trackSubOperation = trackPerformance.startSubOperation("completeValueBdmData["+businessData.getName()+"] SINGLE / storageId"); + resultBdm = new HashMap(); isMultiple=false; contextCaseId.log( "completeValueBdmData.3: Get SIMPLE Business Reference ["+businessData.getName()+"] : type["+businessData.getType()+"]"); @@ -821,6 +789,10 @@ class RestContextHandleGet implements RestApiController { } // logger.info("completeValueBdmData.3bis : Set ["+resultBdm+"] in result"); + if (trackSubOperation!=null) + trackPerformance.endSubOperation( trackSubOperation); + + trackSubOperation = trackPerformance.startSubOperation("getProcessBusinessDataReferences["+businessData.getName()+"] / getClass"); String classDAOName = businessData.getType()+"DAO"; // logger.info("completeValueBdmData.4: Get Business Reference ["+businessData.getName()+"] it's a BDM-type["+businessData.getType()+"] classDao=["+classDAOName+"]"); @@ -837,6 +809,7 @@ class RestContextHandleGet implements RestApiController { BusinessObjectDAO dao = apiClient.getDAO( classDao ); + trackPerformance.endSubOperation( trackSubOperation); // logger.info("completeValueBdmData.6:Dao loaded : dao["+ dao +"] listStorageIds["+listStorageIds+"]"); @@ -864,7 +837,10 @@ class RestContextHandleGet implements RestApiController { } // logger.info("completeValueBdmData.7: Get Business Reference ["+businessData.getName()+"] : type["+businessData.getType()+"] storageId["+storageId+"]"); + trackSubOperation = trackPerformance.startSubOperation("getProcessBusinessDataReferences["+businessData.getName()+"] / findByPersistenceId"); Entity dataBdmEntity = dao.findByPersistenceId(storageId); + trackPerformance.endSubOperation( trackSubOperation); + if (dataBdmEntity==null) { contextCaseId.logError( rootResult, "The BDM variable["+businessData.getName()+"] storageId["+storageId+"] does not exist anymore " ); @@ -889,8 +865,9 @@ class RestContextHandleGet implements RestApiController { // "price":"data" // } // } - - loadBdmVariableOneLevel(rootResult, saveOneBdm, dataBdmEntity, pilotDataMap.get( businessData.getName() ) ); + trackSubOperation = trackPerformance.startSubOperation("loadBdmVariableOneLevel"); + loadBdmVariableOneLevel(rootResult, saveOneBdm, dataBdmEntity, pilotDataMap.get( businessData.getName() ), contextCaseId ); + trackPerformance.endSubOperation( trackSubOperation); } @@ -940,8 +917,11 @@ class RestContextHandleGet implements RestApiController { private void loadBdmVariableOneLevel( Map rootResult, Map saveLocalLevel, Entity dataBdmEntity, - Map contextLocalLevel) + Map contextLocalLevel, + RestContextCaseId contextCaseId) { + RestContextTransformData restContextTransformData= new RestContextTransformData(contextCaseId); + Class classBdmEntity= dataBdmEntity.getClass(); // contextCaseId.log( "loadBdmVariableOneLevel.10a ---------loadBdmVariableOneLevel class["+classBdmEntity.getName()+"] contextLocalLevel["+contextLocalLevel.toString()+"]"); @@ -1064,7 +1044,7 @@ class RestContextHandleGet implements RestApiController { { Map bdmChild = new HashMap(); saveLocalLevel.put(nameAttribute, bdmChild); - loadBdmVariableOneLevel(rootResult, bdmChild, value, contextInfo ) + loadBdmVariableOneLevel(rootResult, bdmChild, value, contextInfo, contextCaseId); } if (value instanceof List) { @@ -1075,13 +1055,13 @@ class RestContextHandleGet implements RestApiController { { Map bdmChild = new HashMap(); listBdmChild.add( bdmChild ); - loadBdmVariableOneLevel(rootResult, bdmChild, valueInList, contextInfo) + loadBdmVariableOneLevel(rootResult, bdmChild, valueInList, contextInfo, contextCaseId); } } } else - saveLocalLevel.put(nameAttribute, transformValue( value, contextLocalLevel==null ? null : contextLocalLevel.get( nameAttribute), contextCaseId )); + saveLocalLevel.put(nameAttribute, restContextTransformData.transformSingleValue( nameAttribute, value, contextLocalLevel==null ? null : contextLocalLevel.get( nameAttribute) )); // logger.info("loadBdmVariableOneLevel.10c saveOneBdm ="+saveLocalLevel.toString()); @@ -1099,58 +1079,6 @@ class RestContextHandleGet implements RestApiController { return fieldType.equals(javassist.util.proxy.MethodHandler.MethodHandler.class); } - /* -------------------------------------------------------------------------------- */ - /* */ - /* transformValue */ - /* */ - /* -------------------------------------------------------------------------------- */ - - /** - * Transform the value accord - */ - private static SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - private static SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); - - private Object transformValue( Object data, String varAction, RestContextCaseId contextCaseId ) - { - if (data==null) - return null; - if (data instanceof Date) - { - contextCaseId.log("========= transformValue["+data+"] varAction["+varAction+"]") - if ("date".equals(varAction)) - return sdfDate.format( (Date) data); - else if ("datetime".equals(varAction)) - return sdfDateTime.format( (Date) data); - else if ("datelong".equals(varAction)) - return ((Date) data).getTime(); - - // use the default - if (contextCaseId.isDateFormatLong() ) - return ((Date) data).getTime(); - if (contextCaseId.isDateFormatTime()) - return sdfDateTime.format( (Date) data); - if (contextCaseId.isDateFormatJson() ) - return sdfDate.format( (Date) data); - - // default : be compatible with the UIDesigner which wait for a timestamp. - return ((Date) data).getTime(); - - } - if (data instanceof List) - { - contextCaseId.log("========= transformValue["+data+"] varAction["+varAction+"]") - List listTransformed= new ArrayList(); - for (Object onItem : ((List) data)) - { - // propagate the varAction to transform the date - listTransformed.add( transformValue( onItem, varAction, contextCaseId )); - } - return listTransformed; - } - return data; - } - /* -------------------------------------------------------------------------------- */ /* */ /* logRest */ diff --git a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextPilot.groovy b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextPilot.groovy index eb18639..ff53998 100644 --- a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextPilot.groovy +++ b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextPilot.groovy @@ -1,5 +1,4 @@ -package org.bonitasoft.rest.context -// package org.bonitasoft.rest.context; +package org.bonitasoft.rest.context; import java.util.logging.Logger @@ -50,29 +49,31 @@ public class RestContextPilot { Map pilotDataMap; + Object contextDataOrigin =null; + String contextDataSt = null; - /** - * after the decodeParameters, we get the cont + /** + * after the decodeParameters, we get the cont */ RestContextCaseId contextCaseId; + RestContextTrackPerformance trackPerformance; + boolean isAllowAllVariables; boolean isPilotDetected=false; - public void setContextCaseId(RestContextCaseId contextCaseId) - { - this.contextCaseId = contextCaseId; + public void setContextCaseId(RestContextCaseId contextCaseId, RestContextTrackPerformance trackPerformance) { + this.contextCaseId = contextCaseId; + this.trackPerformance = trackPerformance; } - /** - * decode the pilot - * @param contextCaseId + /** + * decode the pilot + * @param contextCaseId */ public void decodeParameters() { analysisString=""; errorMessage=null; - Object contextDataOrigin =null; - String contextDataSt = null; pilotDataMap=null; this.isPilotDetected= false; @@ -87,52 +88,18 @@ public class RestContextPilot { // Ok, no worry, let's try different options {} } - if (contextDataOrigin == null && contextCaseId.processInstanceId !=null) - { - try - { - contextDataOrigin = contextCaseId.processAPI.getProcessDataInstance("globalcontext", contextCaseId.processInstanceId); - this.isPilotDetected= true; - contextDataSt = contextDataOrigin.getValue(); - analysisString+="ProcessDataInstance[globalcontext] value="+contextDataOrigin.getValue(); - } catch(DataNotFoundException dnte ) - // ok, maybe no context where given ? - {} - } - if (contextDataOrigin == null && contextCaseId.archivedProcessInstance!=null) - { - try - { - contextDataOrigin = contextCaseId.processAPI.getArchivedProcessDataInstance("globalcontext", contextCaseId.archivedProcessInstance.getSourceObjectId()); - contextDataSt = contextDataOrigin.getValue(); - this.isPilotDetected= true; + // first level is special because the case may be archived. Then, no need to search all the hierarchy (if we have a hierary, that's mean the case is alive) + if (contextDataOrigin == null) + searchContextData(contextCaseId.processInstanceId , contextCaseId.archivedProcessInstance, contextCaseId.processDefinitionId ); - analysisString+="ArchivedProcessDataInstance[globalcontext] value="+contextDataOrigin.getValue(); - } catch(ArchivedDataNotFoundException dnte ) - // still Ok, search after - {} - } + if (contextDataOrigin == null && contextCaseId.processInstanceRoot!=null) + searchContextData(contextCaseId.processInstanceRoot.getId() , null, contextCaseId.processInstanceRoot.getProcessDefinitionId() ); - // Still null ? maybe a parameters exist - // bobparameters - if (contextDataOrigin == null && contextCaseId.processDefinitionId!=null) - { - List listParameters = contextCaseId.processAPI.getParameterInstances(contextCaseId.processDefinitionId, 0, 500, ParameterCriterion.NAME_ASC); - if (listParameters!=null) - for (ParameterInstance parameter : listParameters) - { - if ( "paramcontext".equalsIgnoreCase( parameter.getName() )) - { - contextDataOrigin = parameter; - contextDataSt = parameter.getValue(); - this.isPilotDetected= true; - analysisString+= "Parameters [paramcontext]"; - } - } - } + + // still null and a parent process ? Look here // no data were given : create a default one if (contextDataOrigin == null) @@ -176,9 +143,9 @@ public class RestContextPilot { { return this.isPilotDetected; } - /** - * different getter - * @return + /** + * different getter + * @return */ public Map getPilotDataMap() { @@ -197,9 +164,63 @@ public class RestContextPilot { { return errorMessage; } - + /** + * + */ + private void searchContextData( Long processInstanceId , Long archivedProcessInstanceId, Long processDefinitionId ) + { + if (processInstanceId !=null) + { + try + { + contextDataOrigin = contextCaseId.processAPI.getProcessDataInstance("globalcontext", processInstanceId); + this.isPilotDetected= true; + + contextDataSt = contextDataOrigin.getValue(); + analysisString+="ProcessDataInstance[globalcontext] value="+contextDataOrigin.getValue(); + return; + } catch(DataNotFoundException dnte ) + // ok, maybe no context where given ? + {} + } + if (archivedProcessInstanceId!=null) + { + try + { + contextDataOrigin = contextCaseId.processAPI.getArchivedProcessDataInstance("globalcontext",archivedProcessInstanceId.getSourceObjectId()); + contextDataSt = contextDataOrigin.getValue(); + this.isPilotDetected= true; + + analysisString+="ArchivedProcessDataInstance[globalcontext] value="+contextDataOrigin.getValue(); + return; + } catch(ArchivedDataNotFoundException dnte ) + // still Ok, search after + {} + } + + + // maybe a parameters exist + if (processDefinitionId!=null) + { + List listParameters = contextCaseId.processAPI.getParameterInstances(processDefinitionId, 0, 500, ParameterCriterion.NAME_ASC); + if (listParameters!=null) + for (ParameterInstance parameter : listParameters) + { + if ( "paramcontext".equalsIgnoreCase( parameter.getName() )) + { + contextDataOrigin = parameter; + contextDataSt = parameter.getValue(); + this.isPilotDetected= true; + + analysisString+= "Parameters [paramcontext]"; + return; + } + } + } + } + /* ********************************************************************************* */ /* */ /* Access */ @@ -239,15 +260,16 @@ public class RestContextPilot { return checkPermissionString(varName, permissionControl); } - /** - * this method can be call from a general varName, or for a more complex structure - * @param varName for information only - * @param permissionControl the permission string, a set of "actor:XXX; etc... - * @return + /** + * this method can be call from a general varName, or for a more complex structure + * @param varName for information only + * @param permissionControl the permission string, a set of "actor:XXX; etc... + * @return */ public boolean checkPermissionString(String varName, String permissionControl) { String analysis="isAllowVariableName["+varName+"] found["+permissionControl+"]"; + Map trackSubOperation = trackPerformance.startSubOperation("checkPermissionString["+varName+"]"); boolean allowAccess=false; boolean isOnlyFormatData=true; @@ -284,6 +306,11 @@ public class RestContextPilot { allowAccess=true; isOnlyFormatData=false; } + else if ("admin".equals( onePermission )) + { + allowAccess= contextCaseId.isAdministratorUser(); + analysis+=":admin ? "+allowAccess; + } else if ("initiator".equals( onePermission )) { isOnlyFormatData=false; @@ -335,27 +362,15 @@ public class RestContextPilot { { isOnlyFormatData=false; String actorName = onePermission.substring("actor:".length()); - analysis+=":actorName["+actorName+"] "; - int startIndex=0; - try - { - List listUsersId = contextCaseId.processAPI.getUserIdsForActor(processDefinitionId, actorName, startIndex, 1000); - - while (! allowAccess && listUsersId.size()>0) - { - // logger.info("getUserIdsForActor start at "+startIndex+" found "+listUsersId.size()+" record") - startIndex+= 1000; - if (listUsersId.contains( contextCaseId.userId )) - { - analysis+="part of actor"; - allowAccess=true; - } - else - listUsersId = contextCaseId.processAPI.getUserIdsForActor(processDefinitionId, actorName, startIndex, 1000); - } - }catch (RetrieveException e){ - analysis+=":Actor not found;"; - } + analysis+=":actorName["+actorName+"] "; + Boolean isPart = isPartOfActor( actorName, processDefinitionId ); + if (isPart==null) + analysis+=":Actor not found;" + else if (isPart) + { + analysis+="part of actor"; + allowAccess=true; + } } else if (onePermission.startsWith("format:")) { @@ -375,11 +390,56 @@ public class RestContextPilot { analysis+=";OnlyAFormatData - equals to public"; allowAccess=true; } - contextCaseId.log("analysis: "+analysis+" RESULT="+allowAccess); + contextCaseId.log("RestContextPilot.checkPermissionString : analysis: "+analysis+" RESULT="+allowAccess); + trackPerformance.endSubOperation( trackSubOperation); + return allowAccess; } - - + + /** + * Actor Cache + * + */ + private Map cacheActor= new HashMap(); + + /** + * isPart : return True (part of ) False (not part of ) NULL (actor unknown + * @param actorName + * @return + */ + public Boolean isPartOfActor(String actorName, long processDefinitionId) + { + if (cacheActor.containsKey( actorName )) + { + return cacheActor.get( actorName ); + } + + // calculated and save it + int startIndex=0; + try + { + List listUsersId = contextCaseId.processAPI.getUserIdsForActor(processDefinitionId, actorName, startIndex, 1000); + + while (listUsersId.size()>0) + { + // logger.info("getUserIdsForActor start at "+startIndex+" found "+listUsersId.size()+" record") + startIndex+= 1000; + if (listUsersId.contains( contextCaseId.userId )) + { + cacheActor.put(actorName, Boolean.TRUE ); + return true; + } + else + listUsersId = contextCaseId.processAPI.getUserIdsForActor(processDefinitionId, actorName, startIndex, 1000); + } + }catch (RetrieveException e){ + cacheActor.put(actorName,null); + return null; + // analysis+=":Actor not found;"; + } + cacheActor.put(actorName, Boolean.FALSE ) + return false; + } } \ No newline at end of file diff --git a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextTransformData.groovy b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextTransformData.groovy index 5d6bcb4..8e32fa1 100644 --- a/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextTransformData.groovy +++ b/src/default/restAPIExtensions/ContextAccess/src/main/groovy/org/bonitasoft/rest/context/RestContextTransformData.groovy @@ -12,6 +12,7 @@ import java.util.logging.Logger import java.util.Map; import java.util.StringTokenizer; + import javax.servlet.http.HttpServletRequest @@ -56,7 +57,6 @@ import org.bonitasoft.engine.search.SearchResult // a Case has multiple access : a ProcessInstance or a ArchiveProcessInstance, a TaskInstance or an ArchiveTaskInstance... public class RestContextTransformData { - private static Logger logger = Logger.getLogger("org.bonitasoft.rest.context.RestContextTransformData"); private RestContextCaseId contextCaseId; @@ -73,7 +73,7 @@ public class RestContextTransformData { * @param varValue * @param pilotDataMap */ - private void transform( Map rootResult, String completeName, String varName, Object varValue, Map pilotDataMap, int depth ) + protected void transform( Map rootResult, String completeName, String varName, Object varValue, Map pilotDataMap, int depth ) { if (pilotDataMap==null) return; @@ -124,12 +124,12 @@ public class RestContextTransformData { } else { - boolean isAllowed = contextCaseId.getPilot().checkPermissionString(varName, pilotAction.get( key ) ); + boolean isAllowed = contextCaseId.getPilot().checkPermissionString( key, pilotAction.get( key ) ); trace +=";IsAllow ? "+isAllowed; if (isAllowed) { - subResult.put(key, transformSingleValue( varValueTransformed.get( key ), pilotAction.get( key )==null ? null : pilotAction.get( key ).toString() )); - trace+= "; ["+varName+"]=["+subResult.get( varName )+"]"; + subResult.put(key, transformSingleValue( key, varValueTransformed.get( key ), pilotAction.get( key )==null ? null : pilotAction.get( key ).toString() )); + trace+= "; ["+key+"]=["+subResult.get( varName )+"]"; } } } @@ -175,7 +175,7 @@ public class RestContextTransformData { trace +=";IsAllow ? "+isAllowed; if (isAllowed) { - rootResult.put(varName, transformSingleValue( varValue, pilotAction==null ? "data" : pilotAction.toString() ) ); + rootResult.put(varName, transformSingleValue( varName, varValue, pilotAction==null ? "data" : pilotAction.toString() ) ); trace+= "; ["+varName+"]=["+rootResult.get( varName )+"]"; } } @@ -209,13 +209,16 @@ public class RestContextTransformData { /** * Transform the value accord */ - private static SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + private static SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); private static SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); + private static SimpleDateFormat sdfHourAbsolute = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - private Object transformSingleValue( Object data, String varAction) + private Object transformSingleValue( String varName, Object data, String varAction) { if (data==null) return null; + if (varAction==null) + varAction=""; // varaction can contain multiple element : the access, and the transform. // it maybe : @@ -229,39 +232,56 @@ public class RestContextTransformData { { String token = st.nextToken(); if (token.startsWith("format:")) - translatorAction = token.substring("format:".length()+1); + translatorAction = token.substring("format:".length()); } + Date dataDate=null; if (data instanceof Date) { - logger.info("========= transformValue["+data+"] varAction["+varAction+"]") + dataDate= (Date) data; + } + // JDK 1.8 data type + if (data.getClass().getName().equals("java.time.LocalDate") + || data.getClass().getName().equals("java.time.OffsetDateTime") + || data.getClass().getName().equals("java.time.LocalDateTime")) + { + return RestContextTransformData_18.getTimeFromJDK18( varName, data, translatorAction ); + } + + if (dataDate!=null) + { + contextCaseId.log( "========= transformSingleValue Name ["+varName+"] Date["+dataDate+"] varAction["+varAction+"]") if ("date".equals(translatorAction)) - return sdfDate.format( (Date) data); + return sdfDate.format( dataDate ); else if ("datetime".equals(translatorAction)) - return sdfDateTime.format( (Date) data); + return sdfDateTime.format( dataDate ); else if ("datelong".equals(translatorAction)) - return ((Date) data).getTime(); + return dataDate.getTime(); + else if ("absolute".equals(translatorAction)) + return sdfHourAbsolute.format(dataDate); // use the default if (contextCaseId.isDateFormatLong() ) - return ((Date) data).getTime(); + return dataDate.getTime(); if (contextCaseId.isDateFormatTime()) - return sdfDateTime.format( (Date) data); + return sdfDateTime.format( dataDate); if (contextCaseId.isDateFormatJson() ) - return sdfDate.format( (Date) data); + return sdfDate.format( dataDate); // default : be compatible with the UIDesigner which wait for a timestamp. - return ((Date) data).getTime(); + return dataDate.getTime(); } + + if (data instanceof List) { - logger.info("========= transformValue["+data+"] varAction["+varAction+"]") + contextCaseId.log( "========= transformSingleValue["+data+"] varAction["+varAction+"]") List listTransformed= new ArrayList(); for (Object onItem : ((List) data)) { // propagate the varAction to transform the date - listTransformed.add( transformValue( onItem, varAction, contextCaseId )); + listTransformed.add( transformSingleValue( varName, onItem, varAction )); } return listTransformed; } diff --git a/src/default/restAPIExtensions/ContextAccess/src/main/resources/page.properties b/src/default/restAPIExtensions/ContextAccess/src/main/resources/page.properties index 9cba029..b568edc 100644 --- a/src/default/restAPIExtensions/ContextAccess/src/main/resources/page.properties +++ b/src/default/restAPIExtensions/ContextAccess/src/main/resources/page.properties @@ -85,7 +85,7 @@ apiExtensions=ContextAccess # 2.7 Document permission # -# Access on parameters : in the pilot, the parameter has to be declare (else the "*":"*" return all parameters) +# Permission on parameters : in the pilot, the parameter has to be declare (else the "*":"*" return all parameters) # pilot on parameter : it's possible to declare "paramcontext" as a parameters, and give a context. Then, this context is use. # Priority is # - localcontext @@ -96,20 +96,15 @@ apiExtensions=ContextAccess # Dateformat configuration (Kilian Stein ) # # AccessRight : Check if user can access to what he asks -# in the value, it' possible to use "data", "public", "actor", "initiator", "task" and "format" - # Example - # { - # "firstname" : "data", - # "comment": "initator;task:review", - # "adresse" : { - # "street" : "actor:Verify Adresse", - # "city" : "actor:Verify Adresse", - # } - # } # Fix : # dateFormat bug (Kilian Stein ) - +# 2.8 Ready for 7.5 +# Faster +# Fix bug in the Document Access +# in a sub process, search the Pilot in the sub process OR the root process +# 7.5 ready and accept the new java.time.LocalDate date, and return the data correctly for the 7.5 new Bonita Widget +# # #For each declared API extension, specify the