Uma dúvida muito comum para quem está iniciando em BPEL é como iterar sobre um array. Nesse post vou mostrar como realizar essa tarefa utilizando um elemento For Each. O primeiro passo é criar um projeto BPEL e adicionar o nó For Each. com os valores adequados.
Vá em File, New, SOA Application e clique OK. Dê um nome para a sua aplicação (no meu caso: ExemploForBPELApplication) e clique em Next. Dê um nome para o projeto (ExemploForBPELProject) e clique em Next. Selecione Composite With BPEL Process e clique em Finish. Informe os dados do processo (no nosso exemplo será síncrono) e clique em OK.
Abra o XSD criado. Altere a string de entrada para permitir mais de uma string de entrada. Altere o valor do minOccurs para 0 e do maxOccurs para unbounded. Altere o name para algo mais expressivo, como "nome".
O resultado final é o seguinte:
<!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?> <schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://xmlns.thiagovespa.com.br/ExemploForBPELApplication/ExemploForBPELProject/ExemploForBPELProcess" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="process"> <complexType> <sequence> <element name="nome" type="string" maxOccurs="unbounded" minOccurs="0"/> </sequence> </complexType> </element> <element name="processResponse"> <complexType> <sequence> <element name="result" type="string"/> </sequence> </complexType> </element> </schema>
Abra o processo Bpel. Entre os nós receiveInput e replyOutput, insira uma atividade For Each. Você ficará com algo semelhane à esse:
Edite o For Each. Coloque um nome para o contador (ForEachNomeCounter) e para o For Each (ForEachNome). Se o seu For Each não depender da ordem de execução, marque a opção Parallel Exection. Essa opção otimiza a execução do For Each tornando a execução de forma paralela. Na aba Counter Values, coloque 1 para o Start Value e ora:countNodes('inputVariable','payload','client:nome') para Final Value. O ora:countNodes conta a quantidade de elementos dentro de um nó. Para saber quais valores colocar nos parâmetros, utilize o auto-completar do JDeveloper. Escreva as aspas (') e pressione Ctrl+Espaço e selecione a variável adequada. Dessa forma o nosso For Each vai do valor 1 ao total de elementos passados para o serviço.
Arraste um Assign para dentro do escopo do For Each e atribua o valor:
concat($outputVariable.payload/client:result,' ',$inputVariable.payload/client:nome[$ForEachNomeCounter])
para a variável $outputVariable.payload/client:result
Essa expressão irá concatenar o conteúdo da variavel result, com o espaço e com cada elemento do array client:nome na posição ForEachNomeCounter (que vai de 1 ao total de elementos).
Coloque outro Assign antes do For Each atribuindo 'Olá:' para a variável: $outputVariable.payload/client:result e coloque um outro Assign após o For Each atribuindo o valor concat($outputVariable.payload/client:result,' tudo bem?') para a variável $outputVariable.payload/client:result.
O processo final ficará assim:
Você pode fazer o download do projeto nesse link. Realize o deploy em um servidor SOA e para uma entrada com os seguinte valores:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body xmlns:ns1="http://xmlns.thiagovespa.com.br/ExemploForBPELApplication/ExemploForBPELProject/ExemploForBPELProcess"> <ns1:process> <ns1:nome>Thiago</ns1:nome> <ns1:nome>José</ns1:nome> <ns1:nome>Mária</ns1:nome> </ns1:process> </soap:Body> </soap:Envelope>
Você terá a seguinte saída:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing"> <env:Header> <wsa:MessageID>urn:9F2D8F7050C811E1BF93C7D347E2EB71</wsa:MessageID> <wsa:ReplyTo> <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address> </wsa:ReplyTo> </env:Header> <env:Body> <processResponse xmlns="http://xmlns.thiagovespa.com.br/ExemploForBPELApplication/ExemploForBPELProject/ExemploForBPELProcess"> <result>Olá: Thiago, José, Mária, tudo bem?</result> </processResponse> </env:Body> </env:Envelope>
Agora é só brincar com o código!