Índice
Índice |
---|
outline | true |
---|
style | none |
---|
exclude | .*ndice |
---|
style | none |
---|
|
Considerações Gerais
As informações contidas neste documento têm por objetivo demonstrar como realizar a integração entre o Fluig e aplicativos externos. Para que se tenha uma compreensão completa destas informações, alguns conhecimentos são considerados pré-requisitos, entre eles:
...
Utilize o passo-a-passo para visualizar o processo de criação dos stubs para um serviço disponibilizado pelo Fluig:
Deck of Cards |
---|
history | false |
---|
id | stubFlex |
---|
history | false |
---|
|
Card |
---|
default | true |
---|
effectDuration | 0.5 |
---|
id | 1 |
---|
label | 1º Passo |
---|
effectType | fade |
---|
| A criação dos stubs no Flex® é feito através do menu Data, opção Import WebService(WSDL), conforme a imagem abaixo.
|
Card |
---|
effectDuration | 0.5 |
---|
id | 2 |
---|
label | 2º Passo |
---|
effectType | fade |
---|
| Na primeira janela, é solicitada a pasta dentro do projeto corrente onde devem ser gerados os stubs.
|
Card |
---|
effectDuration | 0.5 |
---|
id | 3 |
---|
label | 3º Passo |
---|
effectType | fade |
---|
| Na tela a seguir, deve ser informado o endereço do WSDL onde se encontra o serviço. Também é possível definir se ele será acessado da estação cliente ou do servidor LifeCycle Data Services.
|
Card |
---|
effectDuration | 0.5 |
---|
id | 4 |
---|
label | 4º Passo |
---|
effectType | fade |
---|
| Na última tela, deve-se informar o package que será utilizado e qual o nome da classe principal (já sugeridos pelo Flex™ Builder™).
|
Card |
---|
effectDuration | 0.5 |
---|
id | 5 |
---|
label | Resultado |
---|
effectType | fade |
---|
| Uma vez finalizado o processo, o Flex™ Builder™ adicionará ao projeto um conjunto de classes que serão utilizadas pelo programador para invocar os serviços, conforme a figura abaixo:
|
|
...
O trecho de código abaixo apresenta um exemplo de invocação do WebService de acesso aos Datasets do Fluig:
Bloco de código |
---|
language | actionscript3 |
---|
theme | Eclipse |
---|
languagefirstline | actionscript31 |
---|
title | ECMDatasetServiceClient.mxml | firstline | 1 |
---|
linenumbers | true |
---|
|
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="{this.start()}">
<mx:Script>
<![CDATA[
import generated.webservices.ValuesDto;
import generated.webservices.DatasetDto;
import generated.webservices.GetDatasetResultEvent;
import generated.webservices.SearchConstraintDtoArray;
import generated.webservices.StringArray;
import generated.webservices.ECMDatasetServiceService;
import mx.rpc.events.FaultEvent;
import mx.collections.ArrayCollection;
//Cria uma instância do Stub de acesso ao serviço
private var ds:ECMDatasetServiceService = new ECMDatasetServiceService();
public function start() : void {
//Cria tipos auxiliares, que serão utilizados na chamado do serviço
var fields:StringArray = new StringArray();
var constraints:SearchConstraintDtoArray = new SearchConstraintDtoArray();
var order:StringArray = new StringArray();
//Define as funções para tratamento do retorno
ds.addEventListener(GetDatasetResultEvent.GetDataset_RESULT, resultGetDataset);
ds.addEventListener(FaultEvent.FAULT,faultGetDataset);
//invoca o método getDataset do serviço
ds.getDataset("adm", 1, "adm", constraints, order, fields, "colleague");
}
//Tratamento dos dados retornados do serviço invocado.
public function resultGetDataset(ev:GetDatasetResultEvent) : void {
//Recupera o retorno do serviço, na forma de um DatasetDto
var dataset:DatasetDto = ev.result as DatasetDto;
//Monta uma string com todos os dados do dataset
var line:String = "";
//Cabeçalho com o nome dos campos
var columnsArray:ArrayCollection = new ArrayCollection(dataset.columns);
for (var j:int = 0; j < columnsArray.length; j++) {
line += columnsArray.getItemAt(j) + "\t";
}
//Linha de dados
var valuesArray:ArrayCollection = new ArrayCollection(dataset.values);
for (var j:int = 0; j < valuesArray.length; j++) {
var row:ValuesDto = valuesArray.getItemAt(j) as ValuesDto;
line += "\n" + j + ":";
for (var i:int = 0; i < row.length; i++) {
line += row.getItemAt(i) + "\t";
}
}
//Mostra a string criada em um textarea na tela
this.sysout.text = line;
}
public function faultGetDataset(ev:FaultEvent) : void {
this.sysout.text = ev.fault.faultString;
}
]]>
</mx:Script>
<mx:TextArea id="sysout" name="sysout" width="100%" height="100%"
paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5"/>
</mx:Application> |
Nota |
---|
Existe um bug do Flex® que impede o funcionamento correto de serviços que trabalhem com matrizes multidimensionais de dados, como no exemplo acima, onde é retornado um array (de linhas do Dataset) de array (das colunas de cada registro). Para contornar este problema, é preciso alterar a classe gerada pelo Flex™ Builder™ que irá encapsular o array multidimensional. No exemplo acima, este classe é a DatasetDto, que deverá ser alterada (linha 11) conforme o exemplo abaixo: Bloco de código |
---|
language | actionscript3 |
---|
theme | Eclipse |
---|
language | actionscript3 |
---|
firstline | 1 |
---|
linenumbers | true |
---|
| public class DatasetDto
{
/**
* Constructor, initializes the type class
*/
public function DatasetDto() {}
[ArrayElementType("String")]
public var columns:Array;
[ArrayElementType("ValuesDto")]
public var values:Array = new Array(); //iniciando o array
} |
Outros serviços que não trabalhem com arrays multidimensionais não exigem alterações no código gerado. |
...
A partir dos stubs gerados, é possível consumir o WebService como no exemplo abaixo:
Bloco de código |
---|
language | java |
---|
theme | Eclipse |
---|
languagefirstline | java1 |
---|
title | ECMDatasetServiceClient.java | firstline | 1 |
---|
linenumbers | true |
---|
|
package com.fluig.examples;
import javax.xml.ws.BindingProvider;
import net.java.dev.jaxb.array.StringArray;
import com.totvs.technology.ecm.dataservice.ws.DatasetDto;
import com.totvs.technology.ecm.dataservice.ws.DatasetService;
import com.totvs.technology.ecm.dataservice.ws.ECMDatasetServiceService;
import com.totvs.technology.ecm.dataservice.ws.SearchConstraintDtoArray;
import com.totvs.technology.ecm.dataservice.ws.ValuesDto;
/*
* Classe para invocar serviço DatasetService
*/
public class ECMDatasetServiceClient {
//Instancia DatasetServiceService.
private ECMDatasetServiceService ecmDatasetServiceService = new ECMDatasetServiceService();
private DatasetService service = ecmDatasetServiceService.getDatasetServicePort();
//Inicia execução da classe
public static void main(String[] args) {
ECMDatasetServiceClient client = new ECMDatasetServiceClient();
//Configura acesso ao WebServices.
BindingProvider bp = (BindingProvider) client.service;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:8080/webdesk/ECMDatasetService");
try {
client.getDataset();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getDataset() throws Exception {
//Cria os parâmetros utilizados na chamada
int companyId = 1;
String username = "adm";
String password = "adm";
String name = "colleague";
StringArray fields = new StringArray();
SearchConstraintDtoArray constraints = new SearchConstraintDtoArray();
StringArray order = new StringArray();
//Invoca o serviço de dataset
DatasetDto result = service.getDataset(
companyId, username, password, name, fields, constraints, order);
//Apresenta o cabeçalho
for (String columnName : result.getColumns()) {
System.out.print(columnName + "\t");
}
System.out.println();
//Apresenta as linhas do dataset
for (ValuesDto row : result.getValues()) {
for (Object value : row.getValue()) {
System.out.print(value + "\t");
}
System.out.println();
}
}
} |
Nota |
---|
Ao utilizar os WebServices via Java™, deve-se atentar para o tipo de cada atributo e para o tipo de retorno do WebService. Por exemplo, para valores do tipo data deve ser utilizado a classe XMLGregorianCalendar: Bloco de código |
---|
language | java |
---|
theme | Eclipse | language |
---|
java | firstline | 1 |
---|
linenumbers | true |
---|
| DocumentDto document = new DocumentDto();
XMLGregorianCalendar date = DatatypeFactory.newInstance().newXMLGregorianCalendar();
date.setYear(2013);
date.setMonth(10);
date.setDay(16);
date.setHour(0);
date.setMinute(0);
date.setSecond(0);
document.setExpirationDate(date); |
|
...
O código abaixo apresenta um exemplo de como consumir o serviço:
Bloco de código |
---|
language | javafx |
---|
theme | Eclipse |
---|
languagefirstline | javafx1 |
---|
title | wsECMDatasetService.p | firstline | 1 |
---|
linenumbers | true |
---|
|
/* Parte I - Invocar o WebService */
DEFINE VARIABLE hWebService AS HANDLE NO-UNDO.
DEFINE VARIABLE hDatasetService AS HANDLE NO-UNDO.
DEFINE VARIABLE cFields AS CHARACTER EXTENT 0 NO-UNDO.
DEFINE VARIABLE cOrder AS CHARACTER EXTENT 0 NO-UNDO.
DEFINE VARIABLE cDataset AS LONGCHAR NO-UNDO.
DEFINE TEMP-TABLE item NO-UNDO
NAMESPACE-URI ""
FIELD contraintType AS CHARACTER
FIELD fieldName AS CHARACTER
FIELD finalValue AS CHARACTER
FIELD initialValue AS CHARACTER.
DEFINE DATASET dConstraints NAMESPACE-URI "http://ws.dataservice.ecm.technology.totvs.com/"
FOR item.
CREATE SERVER hWebService.
hWebService:CONNECT("-WSDL 'http://localhost:8080/webdesk/ECMDatasetService?wsdl'").
RUN DatasetService SET hDatasetService ON hWebService.
RUN getDataset IN hDatasetService(INPUT 1,
INPUT "adm",
INPUT "adm",
INPUT "colleague",
INPUT cFields,
INPUT DATASET dConstraints,
INPUT cOrder,
OUTPUT cDataset).
DELETE OBJECT hDatasetService.
hWebService:DISCONNECT().
DELETE OBJECT hWebService.
/* Parte II - Faz o parser do XML e criar um arquivo texto separado por tabulacao */
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
DEFINE VARIABLE iCount2 AS INTEGER NO-UNDO.
DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hRoot AS HANDLE NO-UNDO.
DEFINE VARIABLE hValues AS HANDLE NO-UNDO.
DEFINE VARIABLE hEntry AS HANDLE NO-UNDO.
DEFINE VARIABLE hText AS HANDLE NO-UNDO.
DEFINE VARIABLE cValue AS CHARACTER NO-UNDO.
OUTPUT TO c:\dataset.txt.
CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hRoot.
CREATE X-NODEREF hEntry.
CREATE X-NODEREF hText.
CREATE X-NODEREF hValues.
hDoc:LOAD("longchar", cDataset, FALSE).
hDoc:GET-DOCUMENT-ELEMENT(hRoot).
/* Percorre as colunas <columns> */
DO iCount = 1 TO hRoot:NUM-CHILDREN WITH 20 DOWN:
hRoot:GET-CHILD(hEntry, iCount).
IF hEntry:NAME <> "columns" THEN
NEXT.
hEntry:GET-CHILD(hText, 1).
PUT UNFORMATTED hText:NODE-VALUE "~t".
DOWN.
END.
PUT UNFORMATTED SKIP.
/* Percorre os registros <values> */
DO iCount = 1 TO hRoot:NUM-CHILDREN WITH 20 DOWN:
hRoot:GET-CHILD(hValues, iCount).
IF hValues:NAME <> "values" THEN
NEXT.
/* Percorre os campos <value> */
DO iCount2 = 1 TO hValues:NUM-CHILDREN:
hValues:GET-CHILD(hEntry, iCount2).
IF hEntry:NUM-CHILDREN = 0 THEN
cValue = "".
ELSE DO:
hEntry:GET-CHILD(hText, 1).
cValue = hText:NODE-VALUE.
END.
PUT UNFORMATTED cValue "~t".
END.
PUT UNFORMATTED SKIP.
END.
OUTPUT CLOSE.
DELETE OBJECT hValues.
DELETE OBJECT hText.
DELETE OBJECT hEntry.
DELETE OBJECT hRoot.
DELETE OBJECT hDoc. |
...
O código abaixo apresenta uma implementação de exemplo do uso de um serviço na construção de um Dataset:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse |
---|
languagefirstline | javascript1 |
---|
title | periodicTable.js | firstline | 1 |
---|
linenumbers | true |
---|
|
function createDataset(fields, constraints, sortFields) {
//Cria o dataset
var dataset = DatasetBuilder.newDataset();
dataset.addColumn("elementName");
// Conecta o servico e busca os livros
var periodicService = ServiceManager.getService('PeriodicTable');
var serviceHelper = periodicService.getBean();
var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
var service = serviceLocator.getPeriodictableSoap();
//Invoca o serviço
try {
var result = service.getAtoms();
var NewDataSet = new XML(result);
for each(element in(var i = 0; i < NewDataSet.Table.length; i++) {
var element = NewDataSet.Table[i];
dataset.addRow(new Array(element.ElementName.toString()));
}
} catch(erro) {
dataset.addRow(new Array(erro));
}
return dataset;
} |
...
Para o serviço da tabela periódica é necessário realizar os seguintes passos:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse | language | javascript |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
var service = serviceLocator.getPeriodictableSoap();
var result = service.getAtoms(); |
...
No caso deste serviço, o método getAtoms retorna uma string contendo um XML com a lista de todos os elementos, conforme o exemplo abaixo:
Bloco de código |
theme |
---|
Eclipse | language | html/xml |
---|
theme | Eclipse |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
<NewDataSet>
<Table>
<ElementName>Actinium</ElementName>
</Table>
<Table>
<ElementName>Aluminium</ElementName>
</Table>
...
</NewDataSet> |
...
O exemplo abaixo apresenta o código utilizado para percorrer o XML retornado:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse | language | javascript |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var NewDataSet = new XML(result);
for each(element in(var i = 0; i < NewDataSet.Table.length; i++) {
var element = NewDataSet.Table[i];
dataset.addRow(new Array(element.ElementName.toString()));
} |
...
Utilizando o exemplo do serviço PeriodicTable apresentado anteriormente, o código da chamada teria as alterações abaixo:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse | language | javascript |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
var service = serviceLocator.getPeriodictableSoap();
var authenticatedService = serviceHelper.getBasicAuthenticatedClient(service, "net.webservicex.PeriodictableSoap", 'usuario', 'senha');
var result = authenticatedService.getAtoms(); |
...
Para personalizar o client que acessa os serviços, é necessário utilizar o método getCustomClient, localizado no provider do serviço (o mesmo que é obtido via ServiceManager). Esta configuração exige a criação de um mapa de parâmetros com seus respectivos valores para passar ao método, conforme snippet abaixo:
Bloco de código |
---|
language | js |
---|
theme | Eclipse | language | js |
---|
|
var properties = {};
properties["basic.authorization"] = "true";
properties["basic.authorization.username"] = "username";
properties["basic.authorization.password"] = "password";
properties["disable.chunking"] = "true";
properties["log.soap.messages"] = "true";
//A propriedade receive.timeout está disponível a partir da versão 1.4.10
properties["receive.timeout"] = "60000";
var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
var service = serviceLocator.getPeriodictableSoap();
var customClient = serviceHelper.getCustomClient(service, "net.webservicex.PeriodictableSoap", properties);
var result = customClient.getAtoms(); |
...
O que indica que temos duas declarações de propriedades conflitantes, conforme o fragmento do WSDL abaixo:
Bloco de código |
---|
theme | Eclipse |
---|
language | html/xml |
---|
theme | Eclipse |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
<s:complexType name="STRUCT_SA1">
<s:sequence>
...
<s:element minOccurs="1" maxOccurs="1" name="_A1COD_MUN" type="s:string"/>
...
<s:element minOccurs="1" maxOccurs="1" name="_A1CODMUN" type="s:string"/>
...
</s:sequence>
</s:complexType> |
...
Para resolver esse conflito, pode ser utilizado o arquivo de bind abaixo :
Bloco de código |
---|
theme | Eclipse |
---|
language | html/xml |
---|
theme | Eclipse |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
<?xml version="1.0" encoding="utf-8"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="http://localhost:8080/pcliente/CHAMTEC.apw?WSDL#types1" node="/xsd:schema">
<jxb:bindings node="//xsd:complexType[@name='STRUCT_SA1']//xsd:sequence//xsd:element[@name='_A1COD_MUN']">
<jxb:property name="_A1COD_MUN2"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings> |
...
O que indica que temos duas propriedades com a identificação "any" no nosso elemento, conforme o fragmento do arquivo WSDL abaixo:
Bloco de código |
---|
theme | Eclipse |
---|
language | html/xml |
---|
theme | Eclipse |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
<s:element name="RealizarConsultaSQLDataTableResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="RealizarConsultaSQLDataTableResult">
<s:complexType>
<s:sequence>
<s:any minOccurs="0" maxOccurs="unbounded" namespace="http://www.w3.org/2001/XMLSchema" processContents="lax" />
<s:any minOccurs="1" namespace="urn:schemas-microsoft-com:xml-diffgram-v1" processContents="lax" />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
...
<s:element name="RealizarConsultaSQLDataTableAuthResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="RealizarConsultaSQLDataTableAuthResult">
<s:complexType>
<s:sequence>
<s:any minOccurs="0" maxOccurs="unbounded" namespace="http://www.w3.org/2001/XMLSchema" processContents="lax" />
<s:any minOccurs="1" namespace="urn:schemas-microsoft-com:xml-diffgram-v1" processContents="lax" />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element> |
...
Para resolver esse conflito, pode ser utilizado o arquivo de bind abaixo :
Bloco de código |
---|
theme | Eclipse |
---|
language | html/xml |
---|
theme | Eclipse |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
<?xml version="1.0" encoding="utf-8"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="http://localhost:8080/tbc/wsConsultaSQL.asmx?WSDL#types1" node="/xsd:schema">
<jxb:bindings node="//xsd:element[@name='RealizarConsultaSQLDataTableResponse']//xsd:sequence//xsd:any[position()=2]">
<jxb:property name="any2"/>
</jxb:bindings>
<jxb:bindings node="//xsd:element[@name='RealizarConsultaSQLDataTableAuthResponse']//xsd:sequence//xsd:any[position()=2]">
<jxb:property name="any2"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings> |
...
Para os três primeiros casos, a lógica de extração das informações desejadas será exposta em um programa com várias procedures, uma para cada necessidade aqui apresentada:
Bloco de código |
---|
language | javafx |
---|
theme | Eclipse |
---|
languagefirstline | javafx1 |
---|
title | CostCenterUtils.p |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
/**************************************************************************
** Utilitário que disponibiliza procedures para a extração de informações
** sobre centros de custo.
**************************************************************************/
DEFINE TEMP-TABLE ttCC NO-UNDO
FIELD conta LIKE conta.ct-codigo /* CHARACTER */
FIELD natureza LIKE conta.natureza /* INTEGER */
FIELD tipo LIKE conta.tipo /* INTEGER */
FIELD titulo LIKE conta.titulo. /* CHARACTER */
/*-------------------------------------------------------------------
Procedure: readCostCenters
Objetivo: Retorna uma temp-table com a lista de centros de custo.
----------------------------------------------------------------------*/
PROCEDURE readCostCenters:
DEFINE OUTPUT PARAMETER TABLE FOR ttCC.
FOR EACH conta:
CREATE ttCC.
ASSIGN
ttCC.conta = conta.ct-codigo
ttCC.natureza = conta.natureza
ttCC.tipo = conta.tipo
ttCC.titulo = conta.titulo.
END.
END.
/*-------------------------------------------------------------------
Procedure: readCostNatureTypes
Objetivo: Retorna uma string com as naturezas dos centros de custo,
separadas por vírgula.
----------------------------------------------------------------------*/
PROCEDURE readCostNatureTypes:
DEFINE OUTPUT PARAMETER cNatureList AS CHARACTER NO-UNDO.
cNatureList = {adinc/i01ad047.i 03}.
END.
/*-------------------------------------------------------------------
Procedure: readCostTypes
Objetivo: Retorna uma string com os tipos de centro de custo,
separados por vírgula.
----------------------------------------------------------------------*/
PROCEDURE readCostTypes:
DEFINE OUTPUT PARAMETER cTypeList AS CHARACTER NO-UNDO.
cTypeList = {adinc/i02ad047.i 3}.
END. |
No caso da extração de usuários comuns aos dois produtos, será utilizado um programa único, conforme o código abaixo:
Bloco de código |
---|
language | javafx |
---|
theme | Eclipse |
---|
languagefirstline | javafx1 |
---|
title | verifyUsers.p | firstline |
---|
1 | linenumbers | true |
---|
|
/**************************************************************************
** Utilitário que recebe um temp-table com uma lista de usuários e retorna
** outra, apenas com os usuários da lista que existam na base de dados.
**************************************************************************/
DEFINE TEMP-TABLE ttUsers
FIELD cod_usuar AS CHARACTER
FIELD nom_usuario AS CHARACTER
INDEX principal IS PRIMARY UNIQUE cod_usuar.
DEFINE TEMP-TABLE ttOutUsers LIKE ttUsers.
DEFINE INPUT PARAMETER TABLE FOR ttUsers.
DEFINE OUTPUT PARAMETER TABLE FOR ttOutUsers.
FOR EACH ttUsers:
IF CAN-FIND(usuar_mestre WHERE usuar_mestre.cod_usuar = ttUsers.cod_usuar) THEN DO:
CREATE ttOutUsers.
BUFFER-COPY ttUsers TO ttOutUsers.
END.
END. |
...
Deck of Cards |
---|
startHidden | false |
---|
effectDuration | 0.5 |
---|
history | false |
---|
id | proxyGen | history | false |
---|
effectType | fade |
---|
|
Card |
---|
default | true |
---|
id | 1 |
---|
label | 1º Passo |
---|
|
- Na primeira tela do ProxyGen, o principal ponto que deve ser observado é o nome do Projeto (no exemplo, EMSProxies). A informação deste campo será utilizada pelo ProxyGen para nomear a classe de acesso ao serviço, e que será utilizada na configuração do serviço no Fluig. Nesta tela também é preciso configurar o PROPATH corretamente, para que seja possível encontrar os arquivos compilados (.r).
|
Card |
---|
|
- O segundo passo consiste em inserir quais procedures serão expostas de forma persistente ou não-persistente. A escolha de qual opção utilizar depende da forma como cada objeto exposto foi construído. Após inseridas as procedures, clicar na opção Generate.
|
Card |
---|
| - Durante o processo de geração do proxy, na aba General, assinalar a opção Java em Client Proxy e informar o diretório onde o proxy será gerado em Output Dir. Observe também o campo AppService, este deve ser o nome do serviço publicado no AppServer, caso contrário não será possível conectar ao servidor.
|
Card |
---|
|
- A última informação relevante para a geração do proxy é o nome do pacote (package) onde as classes serão criadas. Esta informação é utilizada durante a configuração do serviço Progress® no Fluig. Para finalizar clicar no botão OK.
|
Card |
---|
|
- Uma vez criadas as classes, é preciso empacotá-las em um arquivo .JAR. Isto pode ser feito via linha de comando, utilizando-se o comando abaixo:
Sem Formato |
---|
jar -cvf <jar_file_name> <diretorio> |
Observe apenas que no arquivo gerado, é preciso que as classes estejam nos diretórios corretos. No exemplo apresentado, o diretório com deve ser incluído e estar no raiz do arquivo JAR. Por ser compatível com o formato ZIP, uma outra opção é gerar um arquivo com as classes geradas (respeitando-se os diretórios) e renomeá-lo para a extensão .JAR.
|
|
...
O código abaixo apresenta a implementação do Dataset de Tipos de Centro de Custo. A explicação de cada passo da implementação será apresentada após o código:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse |
---|
languagefirstline | javascript1 |
---|
title | dsTipoCentroCusto.js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
function createDataset(fields, constraints, sortFields) {
//Passo 1 - Cria o dataset
var dataset = DatasetBuilder.newDataset();
dataset.addColumn("id");
dataset.addColumn("descricao");
//Passo 2 - Invoca o serviço cadastrado no Fluig
var servico = ServiceManager.getService("EMS2");
//Passo 3 - Carrega o objeto utilitário para integração com Progress
var serviceHelper = servico.getBean();
//Passo 4 - Carrega a procedure persistente CostCenterUtils.p
var remoteObj = serviceHelper.createManagedObject("CostCenterUtils");
//Passo 5 - Invoca a procedure que retorna uma string com os tipos de CC
var types = serviceHelper.createStringHolder();
remoteObj.readCostTypes(types);
//Passo 6 - Quebra a string em um array com cada um dos tipos
var typeArray = types.getStringValue().split(",");
//Passo 7 - Adiciona cada tipo retornado
for(var pos = 0; pos < typeArray.length; pos++) {
dataset.addRow(new Array(pos + 1, typeArray[pos]));
}
return dataset;
} |
...
O Dataset de Natureza dos Centros de Custo é muito similar ao Dataset de tipo de centro de custo. Na prática, a única alteração é a procedure que é chamada:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse |
---|
languagefirstline | javascript1 |
---|
title | dsNaturezaCentroCusto.js | firstline |
---|
1 | linenumbers | true |
---|
|
function createDataset(fields, constraints, sortFields) {
var dataset = DatasetBuilder.newDataset();
dataset.addColumn("id");
dataset.addColumn("descricao");
var servico = ServiceManager.getService("EMS2");
var serviceHelper = servico.getBean();
var remoteObj = serviceHelper.createManagedObject("CostCenterUtils");
var types = serviceHelper.createStringHolder();
remoteObj.readCostNatureTypes(types);
var typeArray = types.getStringValue().split(",");
for(var pos = 0; pos < typeArray.length; pos++) {
dataset.addRow(new Array(pos + 1, typeArray[pos]));
}
return dataset;
} |
...
As temp-table no Progress® 9 são tratadas através de objetos que implementam a interface java.sql.ResultSet:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse |
---|
languagefirstline | javascript1 |
---|
title | dsCentroCustoP9.js | firstline | 1 |
---|
linenumbers | true |
---|
|
function createDataset(fields, constraints, sortFields) {
//Cria a estrutura do Dataset
var dataset = DatasetBuilder.newDataset();
dataset.addColumn("conta");
dataset.addColumn("titulo");
dataset.addColumn("natureza");
dataset.addColumn("tipo");
//Recupera o serviço e carrega o objeto remoto
var servico = ServiceManager.getService("EMS2");
var serviceHelper = servico.getBean();
var remoteObj = serviceHelper.createManagedObject("CostCenterUtils");
//Lê as contas correntes
var holder = serviceHelper.createResultSetHolder();
remoteObj.readCostCenters(holder);
//Percorre os registros, carregando o Dataset com os dados
var rs = holder.getResultSetValue();
while (rs.next()) {
var conta = rs.getObject("conta");
var natureza = rs.getObject("natureza");
var tipo = rs.getObject("tipo");
var titulo = rs.getObject("titulo");
dataset.addRow(new Array(conta, titulo, natureza, tipo));
}
return dataset;
} |
...
No OpenEdge® 10, as temp-tables retornadas são encapsuladas como objetos da classe ProDataGraph. Esta classe também é utilizada quando se utilizam parâmetros do tipo DATASET:
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse |
---|
languagefirstline | javascript1 |
---|
title | dsCentroCustoOE10.js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
function createDataset(fields, constraints, sortFields) {
//Cria a estrutura do Dataset
var dataset = DatasetBuilder.newDataset();
dataset.addColumn("conta");
dataset.addColumn("titulo");
dataset.addColumn("natureza");
dataset.addColumn("tipo");
//Recupera o serviço e carrega o objeto remoto
var servico = ServiceManager.getService("EMS2");
var serviceHelper = servico.getBean();
var remoteObj = serviceHelper.createManagedObject("CostCenterUtils");
//Lê as contas correntes
var holder = serviceHelper.createProDataGraphHolder();
remoteObj.readCostCenters(holder);
//Percorre os registros, carregando o Dataset com os dados
var ttCC = holder.getProDataGraphValue().getProDataObjects("ttCC");
for (var row_index = 0; row_index < ttCC.size(); row_index++) {
var row = ttCC.get(row_index);
dataset.addRow(new Array(row.get("conta"),
row.get("titulo"),
row.get("natureza"),
row.get("tipo")));
}
return dataset;
} |
...
Codificação Progress® 9
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse |
---|
languagefirstline | javascript1 |
---|
title | dsUsuariosComunsP9.js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
function createDataset(fields, constraints, sortFields) {
//Cria o novo Dataset
var dataset = DatasetBuilder.newDataset();
dataset.addColumn("usuario");
dataset.addColumn("nome");
//Recupera os usuários do Fluig
var campos = new Array("colleaguePK.colleagueId", "colleagueName");
var colleaguesDataset = DatasetFactory.getDataset("colleague", campos, null, null);
//Instancia o servico
var servico = ServiceManager.getService("EMS2");
var serviceHelper = servico.getBean();
//Transforma o dataset em um ResultSet (v9) e cria holder para saida
var inputTT = colleaguesDataset.toResultSet();
var holder = serviceHelper.createResultSetHolder();
//Invoca a procedure no Progress
serviceHelper.getProxy().verifyUsers(inputTT, holder);
var rs = holder.getResultSetValue();
while (rs.next()) {
dataset.addRow(new Array(rs.getObject("cod_usuar"), rs.getObject("nom_usuario")));
}
return dataset;
} |
Codificação OpenEdge® 10
Bloco de código |
---|
language | javascript |
---|
theme | Eclipse |
---|
languagefirstline | javascript1 |
---|
title | dsUsuariosComunsOE10.js | firstline | 1 |
---|
linenumbers | true |
---|
|
function createDataset(fields, constraints, sortFields) {
//Cria o novo Dataset
var dataset = DatasetBuilder.newDataset();
dataset.addColumn("usuario");
dataset.addColumn("nome");
//Recupera os usuários do Fluig
var campos = new Array("colleaguePK.colleagueId", "colleagueName");
var colleaguesDataset = DatasetFactory.getDataset("colleague", campos, null, null);
//Instancia o servico
var servico = ServiceManager.getService("EMS2");
var serviceHelper = servico.getBean();
//Transforma o dataset em um ProDataGraph (v10) e cria holder para saida
var inputTT = serviceHelper.toProDataGraph(colleaguesDataset);
var holder = serviceHelper.createProDataGraphHolder();
//Invoca a procedure no Progress
serviceHelper.getProxy().verifyUsers(inputTT, holder);
var ttCC = holder.getProDataGraphValue().getProDataObjects("ttOutUsers");
for (var row_index = 0; row_index < ttCC.size(); row_index++) {
var row = ttCC.get(row_index);
dataset.addRow(new Array(row.get("cod_usuar"), row.get("nom_usuario")));
}
return dataset;
} |
...