コード例 #1
0
 protected string GetCountTarget(Task taskElement)
 {
     if (taskElement.LoopCollection != null)
     {
         if (processConverter.Contract.TryGetProperty(taskElement.LoopCollection, out var property, out var entity))
         {
             if (!entity.IsRootEntity)
             {
                 return(null); //TODO Exception
             }
             if (property.PropertyType == PropertyType.Collection)
             {
                 return($"{property.Name.ToLowerCamelCase()}.length");
             }
             if (property.PropertyType == PropertyType.Dictionary)
             {
                 return($"{ConversionTemplates.MappingKeysArrayName(property.Name.ToLowerCamelCase())}.length");
             }
         }
     }
     else if (taskElement.LoopCardinality != "0")
     {
         return(taskElement.LoopCardinality.ToString());
     }
     return(null); //TODO exception
 }
コード例 #2
0
        public override void ConvertElementLogic()
        {
            processReturnFunction = CreateProcessReturnFunction();
            mainFunction          = new SolidityFunction(GetElementCallName(), SolidityVisibility.Internal);
            mainFunction.AddParameters(processConverter.GetIdentifiersAsParameters());
            var calledStartEventConverter = processConverter.ContractConverter.GetStartEventConverter(callActivity);
            var callSubprocessStatement   = calledStartEventConverter.GetStatementForPrevious(callActivity);

            stateTracker = new SolidityStatement($"uint256 {ConversionTemplates.CallActivityCounter(GetElementCallName())}");
            switch (callActivity.InstanceType)
            {
            case InstanceType.Single:
                //Call the subprocess.
                mainFunction.AddToBody(callSubprocessStatement);
                break;

            case InstanceType.Sequential:
                //Call the subprocess and create a counter.
                mainFunction.AddToBody(new SolidityStatement($"{ConversionTemplates.CallActivityCounter(GetElementCallName())} = 0"));
                mainFunction.AddToBody(callSubprocessStatement);
                break;

            case InstanceType.Parallel:
                //Call all of the subprocesses using an identifier, create a counter.
                mainFunction.AddToBody(new SolidityStatement($"{ConversionTemplates.CallActivityCounter(GetElementCallName())} = 0"));
                var solidityForLoop = new SolidityFor(GetLoopVariable(), GetCountTarget(callActivity));
                solidityForLoop.AddToBody(callSubprocessStatement);
                mainFunction.AddToBody(solidityForLoop);
                break;
            }
        }
コード例 #3
0
        SolidityFunction CreateElementMainFunction()
        {
            SolidityFunction function = new SolidityFunction(GetElementCallName(), SolidityVisibility.Public);

            function.AddModifier($"{ConversionTemplates.StateGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})");
            function.AddParameters(processConverter.GetIdentifiersAsParameters());

            /*
             * if (IsAddressGuardRequired())
             *  function.AddModifier($"{ConversionTemplates.AddressGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})");
             */

            boundaryEventCalls.ForEach(c => function.AddToBody(c));

            function.AddToBody(new SolidityStatement(userTaskElement.ValidationScript, false));


            if (userTaskElement.Form.Fields != null)
            {
                foreach (var field in userTaskElement.Form.Fields)
                {
                    //TODO: throw exception if no property has been found
                    var propertyAndEntity       = processConverter.GetPropertyAndEntity(field.PropertyExpression);
                    var property                = propertyAndEntity.Item1;
                    var entity                  = propertyAndEntity.Item2;
                    var formPropertyDisplayName = Helpers.ToLowerCamelCase(field.DisplayName);


                    function.AddParameter(new SolidityParameter(Helpers.PropertyTypeToString(property, processConverter.ContractConverter), formPropertyDisplayName));
                }
            }

            function.AddToBody(CreateCallNextBody());
            return(function);
        }
コード例 #4
0
        SolidityModifier CreateAddressGuard()
        {
            //Initialize the modifier using the generated name
            SolidityModifier addressGuard = new SolidityModifier(ConversionTemplates.AddressGuardModifierName(GetElementCallName()));

            addressGuard.AddParameters(processConverter.GetIdentifiersAsParameters());
            //Address is force assigned
            if (userTaskElement.Assignee.Address != null)
            {
                SolidityStatement requireStatement = new SolidityStatement($"require(msg.sender=={GetAssigneeAddress()})");
                addressGuard.AddToBody(requireStatement);
            }
            //Address is not force assigned, it will be assigned to the first caller of the first task method containing this assignee
            else if (userTaskElement.Assignee.Name != null)
            {
                var addressPosition = $"{ConverterConfig.ADDRESS_MAPPING_VAR_NAME}[\"{userTaskElement.Assignee.Name}\"]";

                var ifElseBlock = new SolidityIfElse();
                //Assigns the address, if address has not been been yet assigned to the assignee
                ifElseBlock.AddConditionBlock($"{addressPosition} == address(0x0)", new SolidityStatement($"{addressPosition} = msg.sender"));
                //Checks whether the sender has the required address
                SolidityStatement requireStatement = new SolidityStatement($"require(msg.sender=={addressPosition})");
                addressGuard.AddToBody(ifElseBlock);
                addressGuard.AddToBody(requireStatement);
            }
            return(addressGuard);
        }
コード例 #5
0
        SolidityFunction CreateElementMainFunction()
        {
            SolidityFunction function = new SolidityFunction(GetElementCallName(), SolidityVisibility.Public);

            function.AddModifier($"{ConversionTemplates.StateGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})");
            function.AddParameters(processConverter.GetIdentifiersAsParameters());

            /*
             * if (IsAddressGuardRequired())
             *  function.AddModifier($"{ConversionTemplates.AddressGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})");
             */

            boundaryEventCalls.ForEach(c => function.AddToBody(c));

            function.AddToBody(new SolidityStatement(userTaskElement.ValidationScript, false));

            foreach (var fieldGroup in userTaskElement.Form.FieldGroups)
            {
                foreach (var field in fieldGroup.Fields)
                {
                    //var property = processConverter.GetProperty(field.ParamBind);
                    var formPropertyDisplayName = Helpers.ToLowerCamelCase(field.Label);
                    function.AddParameter(new SolidityParameter(Helpers.FormFieldToDataType(field), formPropertyDisplayName));
                }
            }

            function.AddToBody(CreateCallNextBody());
            return(function);
        }
コード例 #6
0
 string GetLoopVariable()
 {
     if (callActivity.LoopCollection != null || callActivity.LoopCardinality != "0")
     {
         return(ConversionTemplates.IdentifierVariableName(callActivity.Id));
     }
     return(null); //TODO exception
 }
コード例 #7
0
 SolidityStatement CreateMultiInstanceCounterDefinition()
 {
     if (userTaskElement.LoopCardinality != 0 || userTaskElement.LoopCollection != null)
     {
         var variableName = ConversionTemplates.MultiInstanceCounterVariable(GetElementCallName());
         return(new SolidityStatement($"uint256 {variableName}"));
     }
     return(null);
 }
コード例 #8
0
        public override SolidityStatement GetStatementForPrevious(ProcessElement previous)
        {
            var statement = new SolidityStatement();

            if (counterVariablePresent)
            {
                statement.Add(new SolidityStatement($"{ConversionTemplates.MultiInstanceCounterVariable(GetElementCallName())} = 0"));
            }
            statement.Add(GetChangeActiveStateStatement(true));
            return(statement);
        }
コード例 #9
0
        public override SolidityStatement GetStatementForPrevious(ProcessElement previous)
        {
            var statement = new SolidityStatement();

            statement.Add(GetChangeActiveStateStatement(true));
            //Call the return function of the parent call element, if it exists
            if (processConverter.ParentProcessConverter != null)
            {
                var callActivityReturnName = ConversionTemplates.CallActivityReturnFunctionName(processConverter.GetParentCallActivityCallName());
                statement.Add($"{callActivityReturnName}({processConverter.ParentProcessConverter.GetIdentifierNames()})");
            }
            return(statement);
        }
コード例 #10
0
        SolidityFunction CreateTouchFunction(TaskConverter attachedToConverter)
        {
            var function = new SolidityFunction($"touch{GetElementCallName()}", SolidityVisibility.Public, "bool");

            function.AddParameters(processConverter.GetIdentifiersAsParameters());
            function.AddModifier($"{ConversionTemplates.StateGuardModifierName(attachedToConverter.GetElementCallName())}({processConverter.GetIdentifierNames()})");

            var solidityCondition = new SolidityIfElse();

            solidityCondition.AddConditionBlock($"now > {GetTimerCondition()}", CreateTouchFunctionLogic(attachedToConverter));
            function.AddToBody(solidityCondition);
            function.AddToBody(new SolidityStatement("return true"));
            return(function);
        }
コード例 #11
0
        SolidityModifier CreateStateGuard()
        {
            SolidityModifier stateGuard = new SolidityModifier(ConversionTemplates.StateGuardModifierName(GetElementCallName()));

            stateGuard.AddParameters(processConverter.GetIdentifiersAsParameters());
            var activeStateFunctionName = ConversionTemplates.ActiveStatesFunctionName(processConverter.Id);
            var callParameters          = processConverter.GetIdentifierNames();

            if (callParameters.Length > 0)
            {
                callParameters += ",";
            }
            callParameters += $"\"{GetElementCallName()}\"";
            SolidityStatement requireStatement = new SolidityStatement($"require({activeStateFunctionName}({callParameters}) == true)");

            stateGuard.AddToBody(requireStatement);
            return(stateGuard);
        }
コード例 #12
0
        SolidityFunction CreateProcessReturnFunction()
        {
            var function = new SolidityFunction(ConversionTemplates.CallActivityReturnFunctionName(GetElementCallName()), SolidityVisibility.Internal);

            function.AddParameters(processConverter.GetIdentifiersAsParameters());

            var nextElementStatement      = CreateNextElementStatement();
            var incrementStatement        = new SolidityStatement($"{ConversionTemplates.CallActivityCounter(GetElementCallName())}++");
            var checkConditionBlock       = new SolidityIfElse();
            var calledStartEventConverter = processConverter.ContractConverter.GetStartEventConverter(callActivity);
            var callSubprocessStatement   = calledStartEventConverter.GetStatementForPrevious(callActivity);

            checkConditionBlock.AddConditionBlock($"{ConversionTemplates.CallActivityCounter(GetElementCallName())} >= {GetCountTarget(callActivity)}",
                                                  nextElementStatement);

            switch (callActivity.InstanceType)
            {
            case InstanceType.Single:
                function.AddToBody(nextElementStatement);
                break;

            case InstanceType.Sequential:
                //increment the counter, check if counter reached limit.
                //If counter reached limit, then call the next element. If not, call the subprocess again.
                function.AddToBody(incrementStatement);

                checkConditionBlock.AddConditionBlock("", callSubprocessStatement);
                function.AddToBody(checkConditionBlock);

                break;

            case InstanceType.Parallel:
                //increment the counter, check if counter reached limit.
                //If counter reached limit, then call the next element. If not, do nothing.
                function.AddToBody(incrementStatement);
                function.AddToBody(checkConditionBlock);
                break;
            }
            return(function);
        }
コード例 #13
0
        List <SolidityComponent> CreateCallNextBody()
        {
            var components        = new List <SolidityComponent>();
            var callNextStatement = GetChangeActiveStateStatement(false);

            callNextStatement.Add(processConverter.GetStatementOfNextElement(userTaskElement));

            if (userTaskElement.InstanceType != InstanceType.Single)
            {
                //The tasks will run until it gets interrupted by some boundary event
                if (userTaskElement.LoopCardinality == -1 || (userTaskElement.LoopCardinality == 0 && userTaskElement.LoopCollection == null))
                {
                    return(components);
                }

                var ifStatement         = new SolidityIfElse();
                var counterVariableName = ConversionTemplates.MultiInstanceCounterVariable(GetElementCallName());

                components.Add(new SolidityStatement($"{counterVariableName}++"));
                counterVariablePresent = true;
                if (userTaskElement.LoopCardinality > 0)
                {
                    ifStatement.AddConditionBlock($"{counterVariableName} >= {userTaskElement.LoopCardinality}", callNextStatement);
                }
                else if (userTaskElement.LoopCollection != null)
                {
                    ifStatement.AddConditionBlock($"{counterVariableName} >= {GetCountTarget(userTaskElement)}", callNextStatement);
                }
                components.Add(ifStatement);
            }
            else
            {
                components.Add(callNextStatement);
            }

            return(components);
        }