Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Índice

 


Índice
outlinetruestylenone
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:


Consideraciones Generales

La información contenida en este documento tiene el objetivo de demostrar cómo realizar la integración entre TOTVS Fluig Plataforma y aplicaciones externas. Para una comprensión completa de esta información, algunos conocimientos se consideran requisitos previos, incluyendo entre ellos:

  • Visión general del producto TOTVS Fluig Plataforma
  • Visión general de la integración
  • Visão geral sobre o produto Fluig
  • Visão geral sobre integração de sistemas
  • JavaScript
  • WebServices
  • SOAP
  • Progress® 4GL

  • Progress® Open App Server
  • Progress® Open Client for Java
  • Datasets (TOTVS Fluig Plataforma)
  • Java™
  • Apache Flex®

Em várias partes deste documento serão apresentados trechos de códigos em diferentes linguagens de programação, com o intuito de demonstrar o uso das capacidades de integração do Fluig. Entretanto, este documento não tem por objetivo capacitar o leitor no uso destas tecnologias além do propósito acima descrito, sendo responsabilidade do leitor buscar informações aprofundadas sobre estas linguagens.

Com o intuito de facilitar o entendimento das informações apresentadas e a simulação dos conceitos apresentados, os exemplos citados neste documento utilizam a funcionalidade de Datasets como exemplo de uso das capacidades de integração do produto. Entretanto, é importante ressaltar que outros pontos do produto possuem disponíveis as mesmas características de integração existentes nos Datasets, em especial as customizações de processos e formulários.

 

Visão Geral

Ainda que empíricos, toda empresa possui processos de negócios que permitem à empresa cumprir o seu objetivo, seja ele a prestação de um serviço, a produção de bens materiais ou o comércio de mercadorias. Uma empresa possui uma infinidade de processos, sendo que cada pessoa na organização obrigatoriamente participa em pelo menos um destes processos, e todos eles trocam informações entre si em algum momento. Os processos podem ser formais (como a contratação de um profissional) ou informais (como um incentivo à inovação), críticos (faturamento) ou satélites (controle de envio de cartões de aniversários).

Com o advento das tecnologias de Sistema da Informação, vários sistemas passaram a dar apoio a estes processos de negócio, especialmente àqueles considerados mais críticos para a operação da empresa. O melhor exemplo disto é a adoção dos sistemas de ERP que dão suporte aos processos de várias áreas da empresa.

O Fluig tem como objetivo ser uma plataforma agnóstica de gestão de processos, documentos e identidades através de uma interface de comunicação colaborativa. Isto pode ser percebido em maior ou menor grau em cada uma das suas funcionalidades, desde as mais simples (como colaboração) até as mais complexas (como DM e BPM).

Entretanto, parte destes processos têm alta dependência dos sistemas de informação já existentes na empresa e, por isso, a arquitetura do Fluig é planejada para permitir integrar-se a estes sistemas, permitindo que os processos modelados tenham maior valor agregado.

O Fluig permite tanto o acesso pelo produto aos sistemas externos (para consultar ou alimentar informações), bem como habilita que outros sistemas venham a conectar-se para a consulta de informações ou para execução de operações transacionais.

 

Image Removed

 

O principal canal de integração do produto é através de WebServices, que vêm se tornando o padrão mais comum de integração com qualquer aplicativo. Através deles, é possível ter acesso às funcionalidades do Fluig e dar acesso pelo produto à aplicativos externos. Este documento dedica uma seção específica sobre integração via WebServices.

A outra forma de integração é via chamadas ao Progress® Open AppServer e é indicada para usuários que precisem integrar o  Fluig com aplicativos desenvolvidos nesta plataforma.

 

WebServices

En varias partes de este documento se presentarán fragmentos de código en diferentes lenguajes de programación, con el fin de demostrar el uso de las capacidades de integración de TOTVS Fluig Plataforma. Sin embargo, este documento no pretende capacitar al lector en el uso de estas tecnologías más allá de los fines anteriormente descritos, siendo responsabilidad del lector buscar información en profundidad sobre estos lenguajes.

Con el fin de facilitar la comprensión de la información que se presenta y la simulación de los conceptos presentados, los ejemplos citados en este documento utilizan la funcionalidad de Datasets como un ejemplo del uso de las capacidades de integración del producto. Sin embargo, es importante señalar que otros puntos del producto tienen disponibles las mismas características de integración existentes en los Datasets, especialmente las personalizaciones de procesos y formularios.

Visión General

Aunque empíricos, todas las empresas tienen procesos de negocio que permiten que la empresa cumpla con su objetivo, ya sea la prestación de un servicio, la producción de bienes materiales o el comercio de mercancías. Una empresa posee una infinidad de procesos, así cada persona en la organización participa obligatoriamente en al menos uno de estos procesos, y todos ellos comparten información entre sí en algún momento. Los procesos pueden ser formales (como la contratación de un profesional) o informales (como un incentivo para la innovación), críticos (facturación) o satélites (control de envío de tarjetas de cumpleaños).

Con la llegada de las tecnologías de Sistema de Información, varios sistemas comenzaron a apoyar estos procesos de negocio, en especial aquellos considerados más críticos para la operación de la empresa. El mejor ejemplo de ello es la adopción de los sistemas ERP que ofrecen soporte a los procesos de varias áreas de la empresa.

TOTVS Fluig Plataforma pretende ser una plataforma agnóstica de gestión de procesos, documentos e identidades a través de una interfaz de comunicación colaborativa. Esto se puede percibir en mayor o menor grado en cada una de sus funcionalidades, desde las más simples (como la colaboración) hasta las más complejas (como DM y BPM).

No obstante, parte de estos procesos dependen en gran medida de los sistemas de información ya existentes en la empresa y por esta razón, la arquitectura de TOTVS Fluig Plataforma está diseñada para permitir la integración a estos sistemas, permitiendo que los procesos modelados tengan mayor valor agregado.

TOTVS Fluig Plataforma permite tanto el acceso por el producto a los sistemas externos (para consultar o alimentar la información) como también posibilita que otros sistemas se conecten para consultar información o para ejecutar operaciones de transacción.


Image Added

El principal canal de integración del producto es a través de WebServices, que se están convirtiendo en el estándar más común de integración con cualquier aplicación. A través de ellos, se puede tener acceso a las funcionalidades de TOTVS Fluig Plataforma y ofrecer acceso por medio del producto a aplicaciones externas. Este documento dedica una sección específica a la integración a través de WebServices.

La otra forma de integración es a través de llamadas a Progress® Open AppServer, que se recomienda para usuarios que necesitan integrar TOTVS Fluig Plataforma con aplicaciones desarrolladas en esta plataforma.

WebServices

La integración a través de WebServices utiliza el protocolo SOAP y, al ser un estándar abierto, permite que sistemas desarrollados en plataformas completamente diferentes como Java ™A integração via WebServices utiliza o protocolo SOAP e, por ser um padrão aberto, permite que sistemas desenvolvidos em plataformas totalmente diferentes como Java™, Microsoft® .Net, C, C ++, PHP, Ruby, Pearl, Python, entre outras, possam trocar informações entre si de forma otras, puedan intercambiar información entre sí de manera transparente.

Acessando os WebServices do Fluig

Acceso a WebServices de TOTVS Fluig Plataforma

TOTVS Fluig Plataforma ofrece un O Fluig disponibiliza um conjunto de WebServices que permitem o acesso às informações do produto ou a execução de tarefas, como iniciar solicitações de processos por exemplo. Para ter a lista dos WebServices disponíveis, acesse o endereçopermiten el acceso a la información del producto o la ejecución de tareas, como por ejemplo iniciar solicitudes de procesos. Para tener la lista de los WebServices disponibles, ingrese a

Sem Formato
http://<host>:<porta>/webdesk/services 

Cada link apresentado direciona o navegador para a URL do WSDL do serviço. O que se muestra dirige el navegador a la URL de WSDL del servicio. WSDL (Web Service Servicio Description Language) possui a descrição do serviço no formato XML e é utilizado pelas ferramentas de desenvolvimento para a criação dos componentes que representarão este serviçotiene la descripción del servicio en formato XML y lo utilizan las herramientas de desarrollo para crear componentes que representarán este servicio.

Nota

Atente para Tenga en cuenta que cada tipo do de atributo que é esperadose espera, por exemplo, o ejemplo el atributo expirationDate do del objeto DocumentDto[] é uma data, porém cada linguagem interpreta de maneira diferente, veja alguns exemplos abaixoes una fecha, pero cada lenguaje lo interpreta de manera diferente, vea a continuación algunos ejemplos:

  • C#: dateTime
  • Java™: XMLGregorianCalendar
  • Progress®: DATETIME-TZ

 

...


Vía Apache Flex®

Como a grande maioria das ferramentas de desenvolvimento, o Al igual que la mayoría de las herramientas de desarrollo, Apache Flex® permite criar crear stubs para o acesso acceder a web services. Estes Estos stubs encapsulam todas as operações de empacotamento e desempacotamento das informações do padrão XML para os tipos nativos da plataforma.

Utilize o passo-a-passo para visualizar o processo de criação dos stubs para um serviço disponibilizado pelo Fluig:

encapsulan todas las operaciones de empaquetado y desempaquetado de la información del estándar XML para los tipos nativos de la plataforma.

Utilice el paso a paso para visualizar el proceso de creación de los stubs para un servicio ofrecido por TOTVS Fluig Plataforma:

Deck of Cards
historyfalse
idstubFlex
Deck of Cards
idstubFlex
historyfalse
Card
defaulttrue
effectDuration0.5
id1
labelPassoPaso
effectTypefade

A criação dos stubs no Flex® é feito através do menu Data, opção La creación de los stubs en Flex® se lleva a cabo a través del menú Data, opción Import WebService(WSDL), conforme a imagem abaixocomo muestra la siguiente imagen.

Image RemovedImage Added

Card
effectDuration0.5
id2
labelPassoPaso
effectTypefade

Na primeira janela, é solicitada a pasta dentro do projeto corrente onde devem ser gerados os En la primera ventana, se solicita la carpeta dentro del proyecto actual donde deben generarse los stubs.

Image RemovedImage Added

Card
effectDuration0.5
id3
labelPassoPaso
effectTypefade

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 En la siguiente pantalla, se debe informar la dirección de WSDL donde se encuentra el servicio. También se puede definir si se accede desde la estación de cliente o desde el servidor LiveCycle Data Services.

Image RemovedImage Added

Card
effectDuration0.5
id4
labelPassoPaso
effectTypefade

Na En la última telapantalla, deve- se debe informar o package que será utilizado e qual o nome da classe principal (já sugeridos pelo el package que se utilizará y cuál es el nombre de la clase principal (ya sugeridos por Flex™ Builder™).

Image RemovedImage Added

Card
effectDuration0.5
id5
labelResultado
effectTypefade

Uma Una 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:

Image Removed

el proceso, Flex ™ Builder ™ agregará al proyecto un conjunto de clases que serán utilizadas por el programador para invocar los servicios, como se muestra a continuación:

Image Added

Informações

Para el ejemplo que se presenta a continuación, se utilizó

Informações

Para o exemplo apresentado abaixo, foi utilizado a IDE Adobe® Flex™ Builder™ 3.0 com con Flex® SDK 3.2. Para outras versões da IDE e/ou SDK, o processo para criação dos stubs pode sofrer algumas variações. 

O trecho de código abaixo apresenta um exemplo de invocação do WebService de acesso aos Datasets do Fluig:

otras versiones de IDE y/o SDK, el proceso de creación de los stubs puede sufrir algunas variaciones. 

El siguiente fragmento de código presenta un ejemplo de invocación de WebService de acceso a los Datasets de TOTVS Fluig Plataforma:

Bloco de código
languageactionscript3
themeEclipse
firstline1
Bloco de código
firstline
themeEclipse
languageactionscript3
titleECMDatasetServiceClient.mxml
1linenumberstrue
<?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;
		
			//CriaCrea umauna instânciainstancia dode Stubstub de acessoacceso aoal serviçoservicio
			private var ds:ECMDatasetServiceService = new ECMDatasetServiceService();

			public function start() : void {

				//CriaCrea tipos auxiliares, que serãose utilizarán utilizadosen nala chamadollamada dode serviçoservicio
				var fields:StringArray = new StringArray();
				var constraints:SearchConstraintDtoArray = new SearchConstraintDtoArray();
				var order:StringArray = new StringArray();

				//Define aslas funçõesfunciones para tratamiento tratamentode dola retornodevolución
				ds.addEventListener(GetDatasetResultEvent.GetDataset_RESULT, resultGetDataset);
				ds.addEventListener(FaultEvent.FAULT,faultGetDataset);
				
				//invoca oel método getDataset dodel serviçoservicio
				ds.getDataset("adm", 1, "adm", constraints, order, fields, "colleague");
			}
			
			//Tratamento dos dados retornados do serviçoTratamiento de los datos devueltos por el servicio invocado.
			public function resultGetDataset(ev:GetDatasetResultEvent) : void {

				//Recupera ola retornodevolución dodel serviçoservicio, naen forma de umun DatasetDto
				var dataset:DatasetDto = ev.result as DatasetDto;

				//MontaInstala umauna string comcon todos oslos dadosdatos dodel dataset
				var line:String = "";
				
				//CabeçalhoEncabezado comcon el onombre nomede doslos campos
				var columnsArray:ArrayCollection = new ArrayCollection(dataset.columns);
				for (var j:int = 0; j < columnsArray.length; j++) {
					line += columnsArray.getItemAt(j) + "\t";
				}

				//LinhaLínea de dadosdatos
				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";
					}
				}
				
				//MostraMuestra ala string criadacreada emen umun textarea en nala telapantalla
				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 un bug do de 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 impide el funcionamiento correcto de servicios que trabajan con matrices multidimensionales de datos, como en el ejemplo anterior, donde se devuelve un array (de líneas del Dataset) de array (das colunas de las columnas de cada registro).

Para contornar solucionar este problema, é preciso alterar a classe gerada pelo es necesario cambiar la clase generada por Flex™ Builder™ que irá encapsular o encapsulará el array multidimensional. No exemplo acima, este classe é a En el ejemplo anterior, esta clase es DatasetDto, que deverá ser alterada (linha 11) conforme o exemplo abaixodeberá cambiarse (línea 11) como se muestra en el siguiente ejemplo:

Bloco de código
language
languageactionscript3
themeEclipse
actionscript3firstline1
linenumberstrue
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 oel array
}

Outros serviços que não trabalhem com arrays multidimensionais não exigem alterações no código gerado.

...

Otros servicios que no trabajan con arrays multidimensionales no exigen cambios en el código generado.


Via Java™

Existem muitas implementações Existen muchas implementaciones de uso de WebServices em Java™ e neste exemplo vamos utilizar as bibliotecas disponíveis no Java™ 7.en Java ™ y en este ejemplo vamos a utilizar las bibliotecas disponibles en Java ™ 7.

Del mismo modo que en el ejemplo anterior, en Apache Flex®, el primer paso consiste en utilizar la dirección WSDL para generar los stubs en Java ™. El siguiente comando presenta un ejemplo de cómo generar estos Da mesma forma como no exemplo anterior, em Apache Flex®, o primeiro passo consiste em utilizar o endereço WSDL para a geração dos stubs em Java™. O comando abaixo apresenta um exemplo de como gerar estes stubs:

Sem Formato
wsimport -d <output_directory> <wsdl_url>

Através deste comando são gerados os stubs no diretório A través de este comando se generan los stubs en el directorio de destino (output_directory), conforme a descrição do arquivo según la descripción del archivo wsdl (wsdl_url).

Image RemovedImage Added

A partir dos de los stubs geradosgenerados, é possível se puede consumir o el WebService como no exemplo abaixose muestra en el siguiente ejemplo:

Bloco de código
firstline
languagejava
themeEclipse
languagefirstlinejava1
titleECMDatasetServiceClient.java
1linenumberstrue
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;

/*
 * ClasseClase para invocar serviçoservicio DatasetService
 */
public class ECMDatasetServiceClient {

	//Instancia DatasetServiceService.
	private ECMDatasetServiceService ecmDatasetServiceService = new ECMDatasetServiceService();
	private DatasetService service = ecmDatasetServiceService.getDatasetServicePort();
	
	//Inicia ejecución execuçãode dala classeclase
	public static void main(String[] args) {
		ECMDatasetServiceClient client = new ECMDatasetServiceClient();
		
		//Configura acessoacceso aoa 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 {
		
		//CriaCrea oslos parâmetrosparámetros utilizados naen la chamadallamada
		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 oel serviçoservicio de dataset
		DatasetDto result = service.getDataset(
				companyId, username, password, name, fields, constraints, order);
		
		//ApresentaPresenta oel cabeçalhoencabezado
		for (String columnName : result.getColumns()) {
			System.out.print(columnName + "\t");
		}
		System.out.println();
		
		//ApresentaPresenta aslas linhaslíneas dodel dataset
		for (ValuesDto row : result.getValues()) {
			for (Object value : row.getValue()) {
				System.out.print(value + "\t");
			}
			System.out.println();
		}
	}

}
Nota

Ao Al utilizar os WebServices via Java™, deve-se atentar para o los WebServices vía Java ™, se debe prestar atención al tipo de cada atributo e para o y al tipo de retorno do devolución de WebService. Por exemploejemplo, para valores do tipo data deve ser utilizado a classe del tipofecha se debe utilizar la clase XMLGregorianCalendar:

Bloco de código
languagejava
themeEclipselanguagejava
firstline1
linenumberstrue
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);

 

...


Vía Progress® 4GL

Assim como nos exemplos anteriores, o primeiro passo para consumir um Webservice em Progress® é utilizar um utilitário que irá ler o endereço WSDL e gerar as informações necessárias para acessá-lo. Diferente do Java™ e Flex®, o Progress® não gera objetos de stub, mas apenas uma documentação sobre como consumir os serviços descritos no arquivo WSDL. Embora em algumas situações seja possível utilizar os tipos nativos do Progress® como parâmetros, dependendo do tipo de dado utilizado é preciso manipular o XML SOAP para extrair ou enviar uma informação.

Al igual que en los ejemplos anteriores, el primer paso para consumir un Webservice en Progress® es utilizar una utilidad que leerá la dirección WSDL y generará la información necesaria para su acceso. A diferencia de Java™ y Flex®, Progress® no genera objetos de stub, pero sí una documentación sobre cómo consumir los servicios descritos en el archivo WSDL. Aunque en algunas situaciones es posible utilizar los tipos nativos de Progress® como parámetros, dependiendo del tipo de dato utilizado es necesario manipular el XML SOAP para extraer o enviar una información.

Para generar la documentación de un servicio, se debe utilizar la utilidad bprowsdldoc como en el siguiente ejemploPara gerar a documentação de um serviço, deve-se utilizar o utilitário bprowsdldoc como no exemplo abaixo:

Sem Formato
bprowsdldoc <URL_TO_WSDL>

Com a execução deste utilitário, serão gerados alguns arquivos HTML com as informações sobre como consumir o serviço. Esta documentação apresenta informações e exemplos de como realizar a conexão com o serviçoe e a utilizar as métodos e datatypes do serviço. 

O código abaixo apresenta um exemplo de como consumir o serviço:

Mediante la ejecución de esta utilidad se generarán algunos archivos HTML con la información sobre la forma de consumir el servicio. Esta documentación proporciona información y ejemplos de cómo llevar a cabo la conexión con el servicio y cómo utilizar los métodos y datatypes del servicio. 

El siguiente código presenta un ejemplo de cómo consumir el servicio:

code
Bloco de código
languagejavafx
themeEclipse
languagefirstlinejavafx1
titlewsECMDatasetService.pfirstline1
linenumberstrue
/* 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.

Acessando WebServices a partir do Fluig

O Fluig permite fazer chamadas a WebServices de terceiros através do cadastro de Serviços na Visualização de Serviços do Fluig Studio.

Acceso a WebServices desde TOTVS Fluig Plataforma

TOTVS Fluig Plataforma permite realizar llamadas a WebServices de terceros a través del registro de Servicios en la visualización de Servicios de Fluig Studio.

Para agregar un nuevo WebService, es necesario ingresar a la opción Incluir Servicio, abriendo el asistente Nuevo Servicio, e informar al servidor de Fluig donde se agregará el servicio, un código identificador para él, su descripción, la URL para WSDL y su tipo (en este caso WebService). En el siguiente ejemplo, se utilizará un WebService público para consultar la tabla periódica, cuya dirección de WSDL es Para adicionar um novo WebService, é preciso clicar na opção Incluir Serviço, abrindo o assistente Novo Serviço, e informar o servidor do Fluig onde será adicionado o serviço, um código identificador para ele, a sua descrição, a URL para o WSDL e o seu tipo (neste caso WebService). No exemplo abaixo, será utilizado um WebService público para consulta à tabela periódica, cujo endereço do WSDL é http://www.webservicex.com/periodictable.asmx?wsdl.

Image Removed

Com base nestas informações, o Fluig irá extrair as informações sobre o WebService informado e finalizará o cadastro deste serviço. 

Uma vez que o serviço esteja cadastrado, é possível visualizar as classes e métodos disponíveis neste serviço e que serão utilizados nos códigos JavaScript que farão uso do mesmo. A tela abaixo apresenta um exemplo de visualização de WebService.

Image Removed

Os serviços adicionados no Fluig podem ser instanciados e utilizados nos pontos onde o produto permite customização utilizando-se JavaScript, como nos scripts para eventos globais, eventos de processos, eventos de definição de formulário ou Datasets. No exemplo a seguir, será criado um Dataset que fará uso deste serviço para trazer os dados da tabela periódica.

O código abaixo apresenta uma implementação de exemplo do uso de um serviço na construção de um Dataset:

Image Added

Basado en esta información, TOTVS Fluig Plataforma extraerá la información sobre el WebService informado y finalizará el registro de este servicio. 

Una vez que el servicio está registrado, se pueden ver las clases y métodos disponibles en este servicio y que se utilizarán en los códigos JavaScript que lo usarán. La siguiente pantalla presenta un ejemplo de visualización de WebService.

Image Added


Los servicios agregados en TOTVS Fluig Plataforma se pueden instanciar y utilizar en los puntos donde el producto permite personalización utilizando JavaScript, como en scripts para eventos globales, eventos de procesos, eventos de definición de formulario o Datasets. En el siguiente ejemplo se creará un Dataset que usará este servicio para traer los datos de la tabla periódica.

El siguiente código presenta una implementación de ejemplo del uso de un servicio en la construcción de un Dataset:

Bloco de código
languagejavascript
themeEclipse
firstline1
titleperiodicTable.js
Bloco de código
themeEclipse
languagejavascript
titleperiodicTable.js
firstline1
linenumberstrue
function createDataset(fields, constraints, sortFields) {

	//CriaCrea oel dataset
	var dataset = DatasetBuilder.newDataset();
	dataset.addColumn("elementName");

	// Conecta oel servicoservicio ey busca oslos livroslibros
	var periodicService = ServiceManager.getService('PeriodicTable');
	var serviceHelper = periodicService.getBean();
	var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
	var service = serviceLocator.getPeriodictableSoap();

	//Invoca oel serviçoservicio
	try {
		var result = service.getAtoms();
		var NewDataSet = new XML(result);
		for each(element in NewDataSet.Table) {
			dataset.addRow(new Array(element.ElementName.toString()));
		}
	} catch(erro) {
		dataset.addRow(new Array(erro));
	}

	return dataset;
}

O primeiro passo El primer paso para invocar o serviço é solicitar ao Fluig que carregue o serviçoel servicio es solicitar a TOTVS Fluig Plataforma que cargue el servicio, a partir do método del método ServiceManager.getService('PeriodicTable'). O El valor passado como parâmetro, deve ser o código utilizado quando cadastrado o serviço.

Uma vez que o serviço tenha sido carregado, é utilizado o método getBean() para retornar um utilitário para acesso às classes do serviço, através do método instantiate. Através deste utilitário, é possível instanciar as classes disponíveis e que estão listadas no cadastro do Serviço (conforme imagem vista anteriormente).

Uma vez que se tenha instanciado o objeto utilitário do serviço, as classes que devem ser instanciadas e os métodos que devem ser invocados dependem de cada WebService utilizado, e deve-se recorrer à sua documentação para mais informações.

Para o serviço da tabela periódica é necessário realizar os seguintes passos:

informado como parámetro debe ser el código utilizado cuando se registró el servicio.

Cuando el servicio se haya cargado, se utiliza el método getBean() para devolver una utilidad para acceder a las clases del servicio, a través del método instantiate. A través de esta utilidad, se pueden instanciar las clases disponibles, que se encuentran en el registro del Servicio (como se puede ver en la imagen anterior).

Después de que se haya instanciado el objeto utilidad del servicio, las clases se deben instanciar y los métodos que se deben invocar depende de cada WebService utilizado y, deben recurrir a su documentación para obtener más información.

Para el servicio de la tabla periódica es necesario realizar los siguientes pasos:

Bloco de código
languagejavascript
themeEclipse
Bloco de código
themeEclipse
languagejavascript
firstline1
linenumberstrue
var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
var service = serviceLocator.getPeriodictableSoap();
var result = service.getAtoms();

OndeDonde:

  • Passo Paso 1: Instanciar a classe la clase net.webservicex.Periodictable para ter acesso ao localizador do serviçotener acceso al localizador del servicio

  • Passo Paso 2: Invocar o método getPeriodictableSoap para instanciar o serviço;Passo 3: Invocar o método getAtoms para ter a lista dos elementos.

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:

  •  Invocar el método getPeriodictableSoap para instanciar el servicio;
  • Paso 3: Invocar el método getAtoms para tener la lista de los elementos.

En el caso de este servicio, el método getAtoms devuelve una string que contiene un XML con la lista de todos los elementos, como se muestra en el siguiente ejemplo:

Eclipse
Bloco de código
Bloco de código
theme
languagehtml/xml
themeEclipse
firstline1
linenumberstrue
<NewDataSet>
	<Table>
		<ElementName>Actinium</ElementName>
	</Table>
	<Table>
		<ElementName>Aluminium</ElementName>
	</Table>
	...
</NewDataSet>

Para percorrer o XML e extrair o dados disponíveis, são utilizadas as funcionalidades de tratamento de XML do JavaScript que facilita a manipulação de dados deste tipo. Para mais informações sobre esta funcionalidade, acesserecorrer el XML y extraer los datos disponibles, se utilizan las funcionalidades de tratamiento de XML de JavaScript que facilita la manipulación de datos de este tipo. Para más información sobre esta funcionalidad, ingrese a http://www.ecma-international.org/publications/standards/Ecma-357.htm ou  ohttp://www.xml.com/pub/a/2007/11/28/introducing-e4x.html.

O exemplo abaixo apresenta o El siguiente ejemplo presenta el código utilizado para percorrer o recorrer el XML retornadodevuelto:

Bloco de código
languagejavascript
themeEclipse
languagejavascript
firstline1
linenumberstrue
var NewDataSet = new XML(result);
for each(element in NewDataSet.Table) {
	dataset.addRow(new Array(element.ElementName.toString()));
}

Uma Una vez implementado o el código do del Dataset, é possível visualizá-lo, conforme a figura abaixo:

Image Removed

 

...

es posible visualizarlo, como muestra la siguiente figura:

Image Added


WebServices con Autenticación Básica

Para consumir WebServices que fazem uso de autenticação utilizan la autenticación básica (WSS ou  o WS-Security), é necessário es necesario utilizar o el método getBasicAuthenticatedClient localizado no en provider do serviço (o mesmo que é obtido via del servicio (el mismo que se obtiene vía ServiceManager). Este método disponibiliza um proporciona un client autenticado.

 

Os parâmetros que devem ser informados no método seguem a ordem abaixo:

  1. Instância do serviço
  2. Nome da classe do serviço
  3. Usuário para a autenticação
  4. Senha para a autenticação

Utilizando o exemplo do serviço PeriodicTable apresentado anteriormente, o código da chamada teria as alterações abaixo:


Los parámetros que se deben informar en el método siguen el siguiente orden:

  1. Instancia del servicio
  2. Nombre de la clase del servicio
  3. Usuario para la autenticación
  4. Contraseña para la autenticación

Utilizando el ejemplo del servicio PeriodicTable presentado anteriormente, el código de la llamada tendría los siguientes cambios:

Bloco de código
languagejavascript
themeEclipse
Bloco de código
themeEclipse
languagejavascript
firstline1
linenumberstrue
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();
WebService

...

con client

...

personalizado
Nota
titleAtençãoAtención

Esta técnica é es válida para o Fluig atualización 1.3.7 ou o superior.

Em integrações que utilizem serviços criados com o CXF com sistemas que não suportam o En integraciones que utilizan los servicios creados con CXF con sistemas que no soportan el protocolo HTTP/1.1 (Protheus, por exemploejemplo), é necessário se debe utilizar este método configurando o parâmetro el parámetro "disable.chunking" com o con el valor "true".

Para customizar o client que acessa os serviços, é necessário utilizar o método personalizar el client que accede al servicio se debe utilizar el método getCustomClient, localizado no en provider do serviço del servicio (o el mesmo que é obtido via se obtiene vía ServiceManager). Esta configuração configuración exige a criação la creación de um un mapa de parâmetros com seus parámetros con sus respectivos valores para passar ao pasar al método, conforme según el siguiente snippet abaixo:

Bloco de código
languagejs
themeEclipse
languagejs
		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";
		
		var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
		var service = serviceLocator.getPeriodictableSoap();
		var customClient = serviceHelper.getCustomClient(service, "net.webservicex.PeriodictableSoap", properties);
		var result = customClient.getAtoms();

 

Os parâmetros que podem ser definidos são os seguintes:


Los parámetros que se pueden configurar son los siguientes:

Propriedad
Función
PropriedadeFunção
basic.authorization
Quando definido

Cuando se define como "true",

faz o mesmo que o

hace lo mismo que el método getBasicAuthenticatedClient,

porém

pero permite aplicar

as configurações de autenticação juntamente com as demais customizações abaixo. Para configurar a autenticação, as propriedades com "username" e "password" abaixo também precisam ser definidas

la configuración de autenticación junto con las demás personalizaciones que se detallan a continuación. Para configurar la autenticación, las siguientes propiedades con "username" y "password" también necesitan definirse.

basic.authorization.username
Usuário a ser utilizado para autenticação
Usuario que se utilizará para autenticación básica.
basic.authorization.password
Senha do usuário
Contraseña de usuario utilizado para
autenticação
autenticación básica.
disable.chunking
Quando definido

Cuando se define como "true",

desabilita o envio de requisições grandes em "pedaços

desactiva el envío de solicitudes grandes en "fragmentos" menores.

Pode

Puede ser útil

quando o serviço chamado não suporta

cuando el servicio llamado no admite este tipo de

requisição

solicitud.

log.soap.messages
Quando definido
Cuando se define como "true", permite que
as mensagens SOAP utilizadas nas requisições feitas aos serviços sejam apresentadas no log do servidor, facilitando a depuração em caso de falhas.

 

los mensajes SOAP utilizados en las solicitudes realizadas a los servicios se presenten en el log del servidor, lo que facilita la depuración en caso de fallas.

Progress® Open AppServer


Assim Así como é possível invocar operações em es posible invocar operaciones en WebServices, o TOTVS Fluig também permite fazer chamadas Plataforma también permite realizar llamadas a programas em en Progress® 4GL (ou o ABL) expostos via expuestos vía Progress® Open AppServer.

Nos exemplos a seguir, serão criados Datasets que, via camada de serviço, farão o acesso à lógicas em 4GL que farão a extração dos dados. Embora os códigos 4GL, neste exemplo, sejam muito simples, eles compreendem os casos mais comuns exigidos no dia-a-dia, uma vez que a complexidade da integração se encontra nas interfaces (parâmetros de entrada e saída) de cada procedure exposta, e não na sua lógica interna.

En los siguientes ejemplos, se crearán Datasets que a través de la capa de servicio, tendrán acceso a las lógicas en 4GL que realizarán la extracción de datos. Aunque los códigos 4GL, en este ejemplo, sean muy simples, abarcan los casos más comunes requeridos en el día a día, ya que la complejidad de la integración se encuentra en las interfaces (parámetros de entrada y salida) de cada procedure expuesto y no en su lógica interna.

Tenga en cuenta que los ejemplos que aquí se presentan pretenden demostrar la dinámica de la integración entre Progress® y TOTVS Fluig Plataforma sin entrar en detalles específicos de las tecnologías involucradas. La capa de servicios Progress® de TOTVS Fluig Plataforma crea una interfaz en JavaScript para la Observe que os exemplos aqui apresentados têm por objetivo demonstrar a dinâmica de integração entre Progress® e o Fluig sem entrar em detalhes específicos das tecnologias envolvidas. A camada de serviço Progress® do Fluig cria uma interface em JavaScript para a biblioteca Java Open AppServer Client, da de Progress® ey, por issolo tanto, para mais informações más información sobre como integrar aplicativos Java™ e Progress® consulte a documentação fornecida pela cómo integrar aplicaciones Java ™ y Progress® vea la documentación suministrada por Progress®.

Caso de Uso

Os exemplos exibidos a seguir, têm por objetivo a criação de quatro Datasets 1 no FluigLos ejemplos que se muestran a continuación, tienen como objetivo crear cuatro Datasets 1 en TOTVS Fluig Plataforma:

  1. Tipos de Centro de CustoCostoque deve retornar os deben devolver los tipos de centro de custo existentes no aplicativo em Progress® (neste caso, o centros de coste existente en la aplicación en Progress® (en este caso, EMS2).
  2. Natureza dos Naturaleza de los Centros de CustoCostoque deve retornar os tipos possíveis de natureza, conforme o aplicativo em Progress® (neste caso, o debe devolver los tipos posibles de naturaleza, según la aplicación en Progress® (en este caso, EMS2).
  3. Centros de CustoCostoque deve retornar os registros na tabela conta debe devolver los registros en la tabla cuenta 2.
  4. Usuários ComunsUsuarios Comunesque deve gerar uma debe generar una lista de usuários comuns usuarios comunes entre o Fluig e o aplicativo em Progress® (utilizando a tabela TOTVS Fluig Plataforma y la aplicación en Progress® (utilizando la tabla usuar_mestre).


    Nota

    1 - Os exemplos utilizam uma base de dados do EMS2 para consulta de centros de custo e usuários. Entretanto, apenas duas tabelas e 6 campos são utilizados no total, o que não deve prejudicar o entendimento da lógica pelo leitor, nem impedir a criação de um esquema equivalente para testes, caso necessário.

    2 - O código apresentado para extração dos centros de custo tem fins meramente didáticos e não pode ser considerado para uso em produção. Para ter mais informações sobre como extrair centros de custos do EMS2, consulte a documentação técnica do mesmo.

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:

  1. Los ejemplos utilizan una base de datos de EMS2 para consultar los centros de costo y los usuarios. No obstante, sólo dos tablas y seis campos se utilizan en total, lo que no debe perjudicar la comprensión de la lógica por parte del lector, ni impedir la creación de un esquema equivalente para pruebas, en caso de ser necesario.

    2 - El código presentado para extracción de los centros de costo tiene fines puramente educativos y no puede considerarse para el uso en producción. Para obtener más información acerca de cómo extraer los centros de costos de EMS2, consulte su documentación técnica.

Para los tres primeros casos, la lógica de extracción de la información deseada estará expuesta en un programa con varios procedures, uno para cada necesidad que aquí se presenta:

Bloco de código
languagejavafx
themeEclipse
firstline1
Bloco de código
themeEclipse
languagejavafx
titleCostCenterUtils.p
firstline1
linenumberstrue
/**************************************************************************
** UtilitárioUtilidad que disponibilizaofrece procedures para ala extraçãoextracción de informaçõesinformación
** sobre centros de custocosto.
**************************************************************************/
DEFINE TEMP-TABLE ttCC NO-UNDO
    FIELD contacuenta    LIKE contacuenta.ct-codigo /* CHARACTER */
    FIELD naturezanaturaleza LIKE contacuenta.naturezanaturaleza  /* INTEGER   */
    FIELD tipo     LIKE contacuenta.tipo      /* INTEGER   */
    FIELD titulo   LIKE contacuenta.titulo.   /* CHARACTER */
  
/*-------------------------------------------------------------------
  Procedure: readCostCenters
   Objetivo: RetornaDevuelve umauna temp-table comcon ala lista de centros de custocosto.
----------------------------------------------------------------------*/
PROCEDURE readCostCenters:
    DEFINE OUTPUT PARAMETER TABLE FOR ttCC.
    FOR EACH contacuenta:
        CREATE ttCC.
        ASSIGN
            ttCC.contacuenta    = contacuenta.ct-codigo
            ttCC.naturezanaturaleza = contacuenta.naturezanaturaleza
            ttCC.tipo     = contacuenta.tipo
            ttCC.titulo   = contacuenta.titulo.
    END.
END.

/*-------------------------------------------------------------------
  Procedure: readCostNatureTypes
   Objetivo: RetornaDevuelve umauna string con comlas asnaturalezas naturezasde doslos centros de custocosto,
             separadas por vírgulacoma.
----------------------------------------------------------------------*/
PROCEDURE readCostNatureTypes:
    DEFINE OUTPUT PARAMETER cNatureList AS CHARACTER NO-UNDO.
    cNatureList = {adinc/i01ad047.i 03}.
END.

/*-------------------------------------------------------------------
  Procedure: readCostTypes
   Objetivo: RetornaDevuelve umauna string comcon oslos tipos de centro de custocosto,
             separados por vírgulacoma.
----------------------------------------------------------------------*/
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 abaixoEn el caso de la extracción de usuarios comunes a los dos productos, se utilizará un único programa, según el siguiente código:

Bloco de código
languagejavafx
themeEclipse
languagefirstlinejavafx1
titleverifyUsers.p
firstline1
linenumberstrue
/**************************************************************************
** UtilitárioUtilidad que receberecibe umuna temp-table comcon umauna lista de usuáriosusuarios ey retornadevuelve
** outraotra, sólo apenascon comlos osusuarios usuáriosde dala lista que existan existamen nala base de dadosdatos.
**************************************************************************/
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.

Os dois códigos apresentados têm diferenças significativas na forma como são utilizados e na forma como serão expostos pelo Progress®. No primeiro, o programa é carregado de forma persistente e suas procedures podem ser executadas de forma independente. No segundo caso, o programa é executado de forma não-persistente e a lógica principal se encontra no main-block. As procedures internas, caso existam, têm por objetivo melhorar a organização do código e não podem ser utilizadas de forma isolada.

Configuração do AppServer

Algumas informações importantes na configuração do AppServer:

Los dos códigos presentados tienen diferencias significativas en la forma en la que se utilizan y en cómo van a ser expuestos por Progress®. En el primer caso, el programa se carga de manera persistente y sus procedures se pueden ejecutar de forma independiente. En el segundo, el programa se ejecuta de manera no persistente y la lógica principal se encuentra en el main-block. Los procedures internos, si existen, están destinados a mejorar la organización del código y no se pueden utilizar de manera aislada.

Configuración de AppServer

Algunas informaciones importantes en la configuración del AppServer:

  1. AppServer debe cargarse en el modo Stateless;
  2. En la configuración del agente, en el campo Propath, se debe agregar el directorio donde están ubicados los archivos

  3. O AppServer deve ser carregado no modo Stateless;
  4. Na configuração do agente, no campo Propath, deve ser adicionado o diretório onde estão localizados os arquivos compilados (.r).

    Nota

    Importante: Quando utilizado um caminho relativo  Cuando se utiliza una ruta relativa (\\servidor\pastacarpeta), o serviço el servicio Windows® do de Progress® (AdminService) deve ser iniciado com um usuário de rede que possua permissão de acesso ao diretório se debe iniciar con un usuario de la red que posea permiso para acceder al directorio informado.

...

Exponiendo códigos 4GL

...

con ProxyGen

O primeiro passo para que seja possível executar rotinas em Progress® 4GL é criar a El primer paso para poder ejecutar rutinas en Progress® 4GL es crear la biblioteca cliente, o que é feito com o uso do aplicativo que se realiza mediante la aplicación ProxyGen, que acompanha a instalação do Progress®, conforme o exemplo abaixo.

Utilize o passo-a-passo para visualizar o processo de criação do proxy:

acompaña a la instalación de Progress®, como se muestra a continuación.

Utilice el paso a paso para visualizar el proceso de creación del proxy: 


Deck of Cards
startHiddenfalse
effectDuration0.5
historyfalse
idproxyGenhistoryfalse
effectTypefade
Card
defaulttrue
id1
label1º Passo
  • Na primeira tela do En la primera pantalla del ProxyGen, o el punto principal ponto que deve ser observado é o nome do Projeto (no exemploque se debe tener en cuenta es el nombre del Proyecto (en el ejemplo, EMSProxies). A informação deste La información de este campo será utilizada pelo por 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 nombrar la clase de acceso al servicio, y se utilizará en la configuración del servicio en Fluig. En esta pantalla también es necesario configurar PROPATH de manera correcta, para que se puedan encontrar los archivos compilados (.r).

Image RemovedImage Added

Card
id2
label2º Passo


  • O El segundo passo consiste em inserir quais procedures serão expostas paso consiste en introducir los procedures que se expondrán de forma persistente ou não-o no 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.La elección de la opción que se va a utilizar depende de la forma en la que se construyó cada objeto expuesto. Después de introducidos los procedures, haga clic en la opción Generate.

Image AddedImage Removed


 
Card
id3
label3º Passo


  • 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. el proceso de generación de proxy, en la pestaña General, marque la opción Java en Client Proxy e ingresar el directorio en el que se generará el proxy en Output Dir. Observe también el campo AppService, éste debe ser el nombre del servicio publicado en AppServer, de lo contrario no se podrá conectar al servidor.

Image AddedImage Removed


Card
id4
label4º Passo


  • A La última informação información 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.

 Image Removed

  • la generación de proxy es el nombre del paquete (package) donde se crearán las clases. Esta información se utiliza durante la configuración del servicio Progress® en Fluig. Para finalizar haga clic en el botón OK.

 Image Added 


Card
id5
labelÚltimo Passo


    Uma vez criadas as classes, é preciso empacotá-las em um arquivo .JAR. Isto pode ser feito via linha
  • Una vez creadas las clases, es necesario empaquetarlas en un archivo .JAR. Esto se puede realizar por línea de comando, utilizando
  • -se o
  • el siguiente 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
<directorio>


Sólo tenga en cuenta que en el archivo generado, es necesario que las clases estén en los directorios correctos. En el ejemplo presentado, el directorio con debe incluirse y estar en la raíz del archivo JAR. Por ser compatible con el formato ZIP, otra opción es generar un archivo con las clases generadas (respetando los directorios) y renombrarlo con la extensión

a extensão

.JAR.


Informações

Dependendo da versão do Progress®, as telas podem sofrer alguma variação na quantidade e disposição dos campos. Consulte a documentação em caso de dúvida

 

 

Configuração do Serviço no Fluig

O cadastro de um serviço é realizado através do Fluig Studio, na view Visualização de Serviços, pela opção Incluir Serviço. A tela abaixo apresenta o assistente de novo serviço e os campos utilizados para o cadastro do serviço Progress®:

Image Removed

 

...

Dependiendo de la versión de Progress®, las pantallas pueden sufrir alguna variación en la cantidad y disposición de los campos. En caso de dudas consulte la documentación



Configuración del Servicio en Fluig

El registro de un servicio se realiza a través de Fluig Studio, en la view Visualización de Servicios, en la opción  Incluir Servicio. La siguiente pantalla muestra el asistente del nuevo servicio y los campos utilizados para el registro del servicio Progress®:


Image Added


  • Donde:

    • ServidorServidor
    do Fluig onde será adicionado o serviço
    • de Fluig donde se agregará el servicio;
    • Código: Código único que
    irá identificar o serviço no
    • identificará el servicio en el sistema. Este código
    será utilizado nos
    • se utilizará en los códigos JavaScript para
    ter acesso
    • acceder a este
    serviço
    • servicio;
    Descrição
    • DescripciónTexto que
    descreve o serviço de dados
    • describe el servicio de datos;
    • URL: Identifica
    a
    • la URL de
    acesso ao serviço
    • acceso al servicio AppServer, como por
    exemplo
    • ejemplo AppServer://<servidor>/<nome_serviço>;
    No
    • En caso de
    não estar utilizando o NameServer padrão deve ser informada a porta de acesso ao NameServer. Ex
    • que no esté utilizando el NameServer estándar se debe informar el puerto de acceso a NameServer Ej.: AppServer://<servidor>:<porta_NameServer>/<nome_serviço>. 
    Observe que dependendo da configuração do serviço e/ou da forma de conexão, a URL pode sofrer alterações. Verifique a documentação do Open AppServer para mais informações
    • Tenga en cuenta que dependiendo de la configuración del servicio y/o de la forma de conexión, la URL puede sufrir cambios. Verifique la documentación de Open AppServer para más información.
    • Tipo: Identifica
    o
    • el tipo de
    serviço
    • servicio (Progress
    ou
    • o WebService).
    Deve ser selecionado
    • Se debe seleccionar Progress;
    • Objeto Remoto: Identifica
    a classe de acesso do proxy. Esta classe normalmente é formada pelo nome do pacote utilizado para a geração das classes Proxy, mais o nome do projeto no
    • la clase de acceso de proxy. Esta clase generalmente está compuesta por el nombre del paquete utilizado para generar las clases Proxy, más el nombre del proyecto en ProxyGen. 
    Exemplo: Nas telas que apresentam o ProxyGen, foi utilizado o pacote
    • Ejemplo: En las pantallas que presentan ProxyGen, se utilizó el paquete com.fluig.samples.ems,
    e o nome dado ao projeto no ProxyGen foi EMSProxies. Neste caso, a classe do Objeto remoto será
    • y el nombre que se dio al proyecto en ProxyGen fue EMSProxies. En este caso, la clase del objeto remoto será com.fluig.samples.ems.EMSProxies;
    Usuário
    • Usuario
    Usuário utilizado na conexão ao serviço, conforme definido nas configurações no
    • Usuario utilizado para conectarse al servicio, como se define en la configuración de AppServer;
    Senha
    • Contraseña
    Senha utilizada na conexão ao serviço, conforme definida nas configurações no
    • Contraseña utilizada para conectarse al servicio, como se define en la configuración de AppServer;
    Parâmetros
    • Parámetros Extras: 
    Parâmetros
    • Parámetros extras (
    e opcionais
    • y opcionales) utilizados para
    conexão ao
    • conectarse a AppServer. Verifique
    a documentação do
    • la documentación de Open AppServer para verificar
    as opções disponíveis em cada versão do
    • las opciones disponibles en cada versión de Progress®;
    Diretório do arquivo
    • Directorio del archivo de Proxy: 
    Arquivo
    • Archivo .JAR
    contendo as classes geradas pelo ProxyGen; Deve ser utilizado o botão Selecionar Arquivo para localizar o mesmo.

Uma vez que o serviço tenha sido adicionado, é possível visualizar as classes disponíveis e os métodos existentes em cada uma delas. Estas informações são importantes para guiar o desenvolvimento dos códigos de customização que farão uso deste serviço. Para visualizar as classes e métodos do serviço, utilize a opção Consulta Serviço na Visualização de Serviços, conforme a tela abaixo:

Image Removed

Visão Geral dos Objetos Envolvidos

O acesso às procedures expostas no AppServer envolve quatro elementos que interagem entre si, conforme o diagrama abaixo:

 

Image Removed

 

Onde:

    • que contiene las clases generadas por ProxyGen. Se debe utilizar el botón Seleccionar Archivo para localizarlo.


Cuando el servicio se haya agregado, se pueden ver las clases disponibles y los métodos existentes en cada una de ellas. Esta información es importante para guiar el desarrollo de los códigos de personalización que harán uso de este servicio. Para ver las clases y los métodos del servicio, utilice la opción Consulta Servicio en Visualización de Servicios, como muestra la siguiente pantalla:

Image Added


Visión general de los objetos involucrados

El acceso a los procedures expuestos en AppServer implica cuatro elementos que interactúan entre sí de acuerdo al siguiente diagrama:


Image Added


Donde:

  • Script Code: es el código en JavaScript que hará uso de los procedures expuestos en AppServer. Como se mencionó anteriormente, este JavaScript puede ser de cualquier naturaleza, tales como la implementación de un Dataset o la personalización de un evento de proceso.
  • Service Provider: Objeto recuperado a través del método ServiceManager.getService que proporciona el acceso a las funcionalidades del servicio. Este objeto se encarga de gestionar la conexión y los recursos asignados por el servicio durante la ejecución del script.
  • Service Helper: Objeto recuperado a través del método getBean en ServiceProvider que pone a disposición un conjunto de métodos de utilidad que permiten, entre otras cosas, crear objetos específicos de
  • Script Code: é o código em JavaScript que fará uso das procedures expostas no AppServer. Como mencionado anteriormente, este JavaScript pode ser de qualquer natureza, como a implementação de um Dataset ou a customização de um evento de processo.
  • Service Provider: Objeto recuperado através do método ServiceManager.getService e que fornece o acesso às funcionalidades do serviço. Este objeto é responsável por gerenciar a conexão e recursos alocados pelo serviço durante a execução do script.
  • Service Helper: Objeto recuperado via método getBean no ServiceProvider e que disponibiliza um conjunto de métodos utilitários que permitem, entre outras coisas, criar objetos específicos do Progress® (StringHolder, ResultSetHolder, etc.), ter acesso ao tener acceso al objeto remoto do de ProxyGen e instanciar classesclases. Para mais informações más información sobre o Service Helper consultar aquiconsulte aquí.
  • ProxyGen Classes: Classes geradas pelo ProxyGen e que serão utilizadas pelo desenvolvedor para execução das rotinas em Progress®. A lista das classes disponíveis, bem como os seus métodos, podem ser visualizados na Visualização de Serviços do Fluig Studio.
 
Procedures Persistentes e Não-Persistentes

Quando uma procedure é adicionada ao projeto do ProxyGen, ela deve ser configurada em duas listas: Procedures Persistentes ou Não-Persistentes. Esta decisão implica diretamente na forma como estes objetos são acessados pela biblioteca gerada e, consequentemente, na forma como o desenvolvedor irá acessá-las nos códigos JavaScript.

  • Clases: Clases generadas por ProxyGen y serán utilizadas por el desarrollador para la ejecución de las rutinas en Progress®. La lista de las clases disponibles, así como sus métodos, se pueden ver en la Visualización de Servicios de Fluig Studio.

Procedures Persistentes y No Persistentes

Cuando se agrega un procedure al proyecto de ProxyGen, éste debe configurarse en dos listas: Procedures Persistentes o No Persistentes Esta decisión implica directamente en la forma en la que se accede a estos objetos por la biblioteca generada y, por consiguiente, en la forma en la que el desarrollador accederá a ella en los códigos JavaScript.

Los procedures expuestos de forma no persistente dan origen a métodos en la clase configurada como Objeto Remoto (o Proxy) en el Servicio, y su ejecución se lleva a cabo llamando al método correspondiente, por ejemploAs procedures expostas de forma não-persistente dão origem à métodos na classe configurada como Objeto Remoto (ou Proxy) no Serviço, e a sua execução é feita chamando o método correspondente, por exemplo:

Sem Formato
serviceHelper.getProxy().verifyUsers(inputTT, holder).

As Los procedures expostas expuestos de forma persistente dão origem à novas classes que podem ser instanciadas via chamadas a métodos no Objeto Remoto (através da Visualização de Serviços no Fluig Studio é possível verificar os métodos disponíveis na classe), ou via o método createManagedObject. A chamada via o método createManagedObject permite que o Fluig tenha controle sobre o ciclo de vida deste objeto, liberando-o automaticamente ao fim do método. Caso o objeto seja instanciado manualmente, o desenvolvedor deve codificar a liberação do objeto (método dan origen a nuevas clases que pueden instanciarse a través de llamadas a métodos en el Objeto Remoto (a través de la Visualización de Servicios en Fluig Studio se pueden verificar los métodos disponibles en la clase), o por el método createManagedObject. La llamada a través del método createManagedObject permite que  Fluig tenga control sobre el ciclo de vida de este objeto, liberándolo de forma automática al final del método. Si el objeto es instanciado de forma manual, el desarrollador debe codificar la liberación del objeto (método _release()), sob bajo pena de bloquear um novo un nuevo agente do de AppServer a en cada invocação do invocación del método.

 

...


Parámetros de Entrada

...

y Salida

Otro punto importante en la invocación de las rutinas en 4GL es observar cuales son tipos de parámetros de entrada y salida de cada procedure o programa. Dependiendo del tipo de dato Outro ponto importante na invocação das rotinas em 4GL é observar quais os tipos de parâmetros de entrada e saída de cada procedure ou programa. Dependendo do tipo de dado (CHARACTER, INTEGER, TEMP-TABLE, etc.), do del tipo de parâmetro parámetro (INPUT, INPUT-OUTPUT, BUFFER, etc.) e da versão utilizada do y de la versión utilizada de Progress®, a la forma de se manipular estes parâmetros pode manipular estos parámetros puede variar.

Para os los tipos mais más simples, como strings, datas ou o valores inteirosenteros, o ProxyGen utiliza um mapeamento direto para os tipos ou classes padrões da linguagem un mapeo directo para los tipos o clases estándares del lenguaje Java™. Para tipos complexoscomplejos, como temp-tables e y buffers, o ProxyGen utiliza classes clases que fazem forman parte da de la biblioteca de runtime destes serviçosde estos servicios.

Quando os parâmetros são Cuando los parámetros son de entrada e saída y salida (INPUT-OUTPUT) ou o de saída salida (OUTPUT), os los tipos primitivos precisam ser substituídos por classes deben sustituirse por clases Holders, que conterão o valor retornado após a execução do método. Os exemplos mais comuns são StringHolder ou ResultSetHolder.

Os tipos de dados utilizados em cada método podem ser consultado através da Visualização de Serviços no Fluig Studio. Observe que dependendo da versão do Progress® pode haver variação nos tipos de parâmetros utilizados e na forma de utilizá-los. Em caso de dúvida, consulte a documentação fornecida pela Progress®.

Criação dos Datasets

Uma vez que o serviço Progress® tenha sido adicionado no Fluig, é possível utilizá-lo nos pontos onde o produto permite customização utilizando-se JavaScript, como nos scripts para eventos globais, eventos de processos, eventos de definição de formulário ou Datasets.

A forma de se invocar as rotinas expostas pelo serviço é sempre a mesma, independente de qual ponto está sendo chamado. Entretanto, para facilitar o entendimento do uso dos serviços Progress® no Fluig e facilitar a reprodução dos exemplos apresentados no ambiente do leitor, todos os exemplos abaixo utilizarão Datasets como alvo.

Conforme visto anteriormente, os Datasets que serão apresentados aqui são Tipos de Centro de Custo, Natureza dos Centros de Custo, Centros de Custo e Usuários em Comum.

 

Tipos de Centro de Custo

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:

contendrán el valor devuelto después de la ejecución del método. Los ejemplos más comunes son StringHolder o ResultSetHolder.

Los tipos de datos utilizados por cada método se pueden consultar a través de la Visualización de Servicios en Fluig Studio. Tenga en cuenta que dependiendo de la versión de Progress® puede existir variación en los tipos de parámetros utilizados y en la manera de utilizarlos. En caso de duda, consulte la documentación suministrada por Progress®.

Creación de los Datasets

Cuando el servicio Progress® se haya agregado en Fluig, es posible utilizarlo en los puntos donde el producto permite la personalización utilizando JavaScript, como en los scripts para eventos globales, eventos de procesos, eventos de definición de formulario o Datasets.

La forma de invocar las rutinas expuestas por el servicio es siempre la misma, independientemente de qué punto se está llamando. Sin embargo, para facilitar la comprensión del uso de servicios Progress® en Fluig y facilitar la reproducción de los ejemplos presentados en el entorno del lector, todos los siguientes ejemplos utilizarán Datasets como meta.

Como ya se ha visto anteriormente, los Datasets que se presentarán aquí son Tipos de Centro de CostoNaturaleza de los Centros de CostoCentros de Costo yUsuarios en Común.


Tipos de Centro de Costo

El siguiente código presenta la implementación del Dataset de Tipos de Centro de Costo. La explicación de cada paso de la implementación se presentará después del código:

Bloco de código
languagejavascript
themeEclipse
firstline1
titledsTipoCentroCusto.js
Bloco de código
themeEclipse
languagejavascript
titledsTipoCentroCusto.js
firstline1
linenumberstrue
function createDataset(fields, constraints, sortFields) {
	
	//PassoPaso 1 - CriaCrea oel dataset
	var dataset = DatasetBuilder.newDataset();
    dataset.addColumn("id");
    dataset.addColumn("descricaodescripcion");
     
	//PassoPaso 2 - Invoca oel serviçoservicio cadastradoregistrado noen Fluig
	var servico = ServiceManager.getService("EMS2");
  
	//PassoPaso 3 - CarregaCarga oel objeto utilitárioutilidad para integraçãointegración comcon Progress
    var serviceHelper = servico.getBean();
  
	//PassoPaso 4 - CarregaCarga ael procedure persistente CostCenterUtils.p
    var remoteObj = serviceHelper.createManagedObject("CostCenterUtils");

	//PassoPaso 5 - Invoca ael procedure que retornadevuelve umauna string comcon oslos tipos de CC
    var types = serviceHelper.createStringHolder();
    remoteObj.readCostTypes(types);

	//PassoPaso 6 - QuebraRompe ala string emen umun array comcon cada uno umde doslos tipos
    var typeArray = types.getStringValue().split(",");
  
	//PassoPaso 7 - AdicionaAgrega cada tipo retornadodevuelto
    for(var pos = 0; pos < typeArray.length; pos++) {
        dataset.addRow(new Array(pos + 1, typeArray[pos]));
    }

    return dataset;
}

 


OndeDonde:

  • Passo Paso 1: Cria o dataset e adiciona os campos do mesmo;Crea el dataset y agrega los campos del mismo;
  • Paso 2: La invocación del servicio registrada en Fluig se realiza por el método Passo 2: É feita a invocação do serviço cadastrado no Fluig, através do método ServiceManager.getService, e o y el valor passado pasado como parâmetro deve parámetro debe ser o el código do serviço. Note que neste ponto não é preciso informar qualquer parâmetro de conexão ao serviço, uma vez que isto já foi feito no seu cadastro;
  • Passo 3: Utiliza o método getBean para retornar um objeto utilitário para serviços Progress®. Este utilitário disponibiliza uma série de métodos que facilitam a interação com o proxy gerado e seus métodos serão apresentados em mais detalhes adiante neste documento;
  • Passo 4: Faz a carga do objeto CostCenterUtils de forma gerenciada, através do método createManagedObject do utilitário criado anteriormente;
  • Passo 5: Invoca o método desejado, neste caso o readCostTypes, passando um StringHolder que irá receber o valor de saída;
  • Passo 6: Transforma a String recebida por parâmetro em um array com as opções. O caractere , (vírgula) é utilizado para determinar os pontos de quebra da string;
  • Passo 7: Percorre o array criado, adicionando uma linha no Dataset para cada item do array. 

A tela abaixo apresenta a visualizaçào dos dados do Dataset criado:

Image Removed

 

Natureza dos Centros de Custo

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:

  • del servicio. Tenga en cuenta que en este punto no es necesario informar ningún parámetro de conexión al servicio, puesto que esto ya se realizó en su registro;
  • Paso 3: Utiliza el método getBean para devolver un objeto utilidad para servicios Progress®. Esta utilidad proporciona una serie de métodos que facilitan la interacción con el proxy generado y sus métodos se presentarán con más detalle, más adelante en este documento;
  • Paso 4: Realiza la carga del objeto CostCenterUtils de manera gestionada, a través del método createManagedObject de la utilidad creada anteriormente;
  • Paso 5: Invoca el método deseado, en este caso readCostTypes, pasando un StringHolder que recibirá el valor de salida;
  • Paso 6: Transforma la string recibida como parámetro en un array con las opciones. El carácter , (como) se utiliza para determinar los puntos de ruptura de string;
  • Paso 7: Recorre el array creado, agregando una línea en el Dataset para cada ítem del array. 


La siguiente pantalla presenta la visualización de los datos del Dataset creado:

Image Added
Naturaleza de los Centros de Costo

El Dataset de Naturaleza de los Centros de Costo es muy similar al Dataset de tipo de centros de costo. En la práctica, el único cambio es que el procedure se llama:

Bloco de código
languagejavascript
themeEclipse
firstline1
Bloco de código
themeEclipse
languagejavascript
titledsNaturezaCentroCusto.js
firstline1
linenumberstrue
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;
}

 

Após o cadastro do Dataset, é possível visualizar o seu conteúdo:

Image Removed


Después del registro del Dataset, se puede ver su contenido:

Image Added 


Centros de

...

Costo

O El Dataset de Centros de Custo possui uma estrutura muito semelhante aos dois Datasets vistos anteriormente. A diferença principal é que, neste caso, a procedure retorna uma temp-table com os centros de custo, o que altera a forma como os dados são manipulados.de Centro de Costo posee una estructura muy similar a la de los dos Dataset visto anteriormente. La principal diferencia es que, en este caso, el procedure devuelve una temp-table con los centros de costos, lo que cambia la forma en la que se manipulan los datos.

Dependiendo de la versión de Progress®, los objetos utilizados pueden variar. A continuación, se presentan ejemplos de la codificación para Progress® 9 y Dependendo da versão do Progress®, os objetos utilizados podem variar. A seguir, são apresentados exemplos da codificação para Progress® 9 e OpenEdge® 10, respectivamente. Em En ambos os casos, o el resultado apresentado pelo presentado por Dataset será o mesmoel mismo.

...

Codificación Progress® 9

As Las temp-table no en Progress® 9 são tratadas através de objetos que implementam a interface son manejadas por los objetos que implementan la interfaz java.sql.ResultSet:

Bloco de código
languagejavascript
themeEclipse
languagefirstlinejavascript1
titledsCentroCustoP9.js
firstline1
linenumberstrue
function createDataset(fields, constraints, sortFields) {
    
	//CriaCrea ala estruturaestructura dodel Dataset
    var dataset = DatasetBuilder.newDataset();
    dataset.addColumn("contacuenta");
    dataset.addColumn("titulo");
    dataset.addColumn("naturezanaturaleza");
    dataset.addColumn("tipo");
    
	//Recupera oel serviçoservicio ey carregacarga oel objeto remoto
    var servico = ServiceManager.getService("EMS2");
    var serviceHelper = servico.getBean();
    var remoteObj = serviceHelper.createManagedObject("CostCenterUtils");
    
    //Lee aslas contascuentas correntescorrientes
    var holder = serviceHelper.createResultSetHolder();
    remoteObj.readCostCenters(holder);
    
    //PercorreRecorre oslos registros, carregandocargando oel Dataset comcon oslos dadosdatos
    var rs = holder.getResultSetValue();
    while (rs.next()) {
        var contacuenta 	 = rs.getObject("contacuenta");
        var naturezanaturaleza = rs.getObject("naturezanaturaleza");
        var tipo 	 = rs.getObject("tipo");
        var titulo   = rs.getObject("titulo");
	
        dataset.addRow(new Array(contacuenta, titulo, naturezanaturaleza, tipo));
    }
    
    return dataset;
}

...

Codificación OpenEdge® 10

No En OpenEdge® 10, as las temp-tables retornadas são encapsuladas devueltas se encapsulan como objetos da classe de la clase ProDataGraph. Esta classe também é utilizada quando se utilizam parâmetros do clase también se utiliza cuando se usan parámetros del tipo DATASET:

Bloco de código
languagejavascript
themeEclipse
languagefirstlinejavascript1
titledsCentroCustoOE10.jsfirstline1
linenumberstrue
function createDataset(fields, constraints, sortFields) {
    
	//CriaCrea ala estruturaestructura dodel Dataset
    var dataset = DatasetBuilder.newDataset();
    dataset.addColumn("contacuenta");
    dataset.addColumn("titulo");
    dataset.addColumn("naturezanaturaleza");
    dataset.addColumn("tipo");
    
	//Recupera oel serviçoservicio ey carregacarga oel objeto remoto
    var servico = ServiceManager.getService("EMS2");
    var serviceHelper = servico.getBean();
    var remoteObj = serviceHelper.createManagedObject("CostCenterUtils");
    
    //Lee aslas contascuentas correntescorrientes
    var holder = serviceHelper.createProDataGraphHolder();
    remoteObj.readCostCenters(holder);
    
	//PercorreRecorre oslos registros, carregandocargando oel Dataset comcon oslos dadosdatos
    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("contacuenta"),
                                 row.get("titulo"),
                                 row.get("naturezanaturaleza"),
                                 row.get("tipo")));
    }
    
    return dataset;
}

 


Visualização do Visualización del Dataset:

Image RemovedImage Added

 

Usuários em Comum

A primeira diferença entre o Dataset de usuários comuns e os exemplos anteriores, é que neste caso é preciso passar uma temp-table como parâmetro para a procedure invocada.

A segunda diferença é que o código 4GL está implementado em um programa não-persistente, o que altera a forma como a lógica é invocada a partir do código JavaScript.

A terceira diferença que pode se observar neste caso é que é possível transformar um Dataset nos tipos de dados requeridos pelo Progress® (ResultSet ou ProDataGraph).

 

Codificação Progress® 9

 


Usuarios en Común

La primera diferencia entre el Dataset de usuarios comunes y los ejemplos anteriores, es que en este caso es necesario pasar una temp-table como parámetro al procedure invocado.

La segunda diferencia es que el código 4GL se implementa en un programa no persistente, lo que cambia la forma como la lógica se invoca desde el código JavaScript.

La tercera diferencia que se puede observar en este caso es que es posible transformar un Dataset en los tipos de datos requeridos por Progress® (ResultSet o ProDataGraph).

Codificación Progress® 9
Bloco de código
languagejavascript
themeEclipse
firstline1
Bloco de código
themeEclipse
languagejavascript
titledsUsuariosComunsP9.jsfirstline1
linenumberstrue
function createDataset(fields, constraints, sortFields) {
    
    //CriaCrea oel novonuevo Dataset
    var dataset = DatasetBuilder.newDataset();
    dataset.addColumn("usuario");
    dataset.addColumn("nomenombre");
    
	//Recupera los osusuarios usuáriosde doTOTVS Fluig Plataforma
    var campos = new Array("colleaguePK.colleagueId", "colleagueName");
    var colleaguesDataset = DatasetFactory.getDataset("colleague", campos, null, null);
    
    //Instancia oel servicoservicio
    var servico = ServiceManager.getService("EMS2");
    var serviceHelper = servico.getBean();
     
    //Transforma oel dataset emen umun ResultSet (v9) ey criacrea holder parade saidasalida
    var inputTT = colleaguesDataset.toResultSet();
    var holder = serviceHelper.createResultSetHolder();
    
    //Invoca ael procedure en noel 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;
}

...

Codificación OpenEdge® 10

...

code
Bloco de código
language
javascript
themeEclipse
languagefirstlinejavascript1
titledsUsuariosComunsOE10.jsfirstline1
linenumberstrue
function createDataset(fields, constraints, sortFields) {
    
	//CriaCrea oel novonuevo Dataset
    var dataset = DatasetBuilder.newDataset();
    dataset.addColumn("usuario");
    dataset.addColumn("nomenombre");
    
	//Recupera oslos usuarios usuáriosde doTOTVS Fluig Plataforma
    var campos = new Array("colleaguePK.colleagueId", "colleagueName");
    var colleaguesDataset = DatasetFactory.getDataset("colleague", campos, null, null);
    
    //Instancia oel servicoservicio
    var servico = ServiceManager.getService("EMS2");
    var serviceHelper = servico.getBean();
	
    //Transforma oel dataset emen umun ProDataGraph (v10) ey criacrea holder parade saidasalida
    var inputTT = serviceHelper.toProDataGraph(colleaguesDataset);
    var holder = serviceHelper.createProDataGraphHolder();
    
    //Invoca ael procedure en noel 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;
}

 

Visualização do Dataset:

Image Removed


Visualización del Dataset:

Image Added Âncoraservicehelperservicehelper 


Service Helper

A tabela abaixo apresenta a La siguiente tabla presenta la lista de métodos existentes na classe utilitária para serviços en la clase utilidad para servicios Progress®:

Retorno
Devolución
Método
e Descrição
y Descripción
java.lang.ObjectcreateBigDecimalHolder()
Cria um
Crea un objeto Holder para
o
el tipo DECIMAL
java.lang.ObjectcreateBooleanHolder()
Cria um
Crea un objeto Holder para
o
el tipo LOGICAL
java.lang.ObjectcreateByteArrayHolder()
Cria um
Crea un objeto Holder para
o
el tipo RAW
java.lang.ObjectcreateCOMHandleHolder()
Cria um
Crea un objeto Holder para
o
el tipo COM-HANDLE
java.lang.ObjectcreateDateHolder()
Cria um
Crea un objeto Holder para
o
el tipo DATE
java.lang.ObjectcreateHandleHolder()
Cria um
Crea un objeto Holder para
o
el tipo WIDGET-HANDLE (Handle)
java.lang.ObjectcreateIntHolder()
Cria um
Crea un objeto Holder para
o
el tipo INTEGER
java.lang.ObjectcreateLongHolder()
Cria um
Crea un objeto Holder para
o
el tipo RECID
java.lang.ObjectcreateManagedObject(java.lang.String objName)
Lê um arquivo
Lee un archivo .p
ou
o .r que
tenha sido exposto via
haya sido expuesto a través de AppServer de forma persistente.
Através deste método o provedor do serviço pode gerenciar o
 A través de este método el proveedor del servicio puede administrar el ciclo de vida
destes
de estos objetos,
liberando-os ao final da execução do
liberándolos al final de la ejecución del script.
java.lang.ObjectcreateMemptrHolder()
Cria um
Crea un objeto Holder para
o
el tipo MEMPTR
java.lang.ObjectcreateProDataGraph(java.lang.Object metadata)
Cria um objeto da classe
Crea un objeto de la clase ProDataGraph
java.lang.ObjectcreateProDataGraphHolder()
Cria um
Crea un objeto Holder para
o
el tipo ProDataGraphHolder
java.lang.ObjectcreateProDataGraphMetaData(java.lang.String name)
Cria um objeto da classe
Crea un objeto de la clase ProDataGraphMetadata
java.lang.ObjectcreateProDataObjectMetaData(java.lang.String tableName, int numFields, boolean bimageFlag, int numIndexes, java.lang.String multiIxCols, java.lang.String XMLNamespace, java.lang.String XMLPrefix)
Cria um objeto da classe
Crea un objeto de la clase ProDataObjectMetadata.
Cria um
Crea un objeto para
um
un dataset (Temp-table).
java.lang.ObjectcreateResultSetHolder()
Cria um
Crea un objeto Holder para
o
el tipo TABLE
java.lang.ObjectcreateRowidHolder()
Cria um
Crea un objeto Holder para
o
el tipo ROWID
java.lang.ObjectcreateStringHolder()
Cria um
Crea un objeto Holder para
o
el tipo CHARACTER.
java.lang.ObjectgetProxy()
Retorna a instância do
Devuelve la instancia del objeto de
conexão ao
conexión a AppServer,
ya conectado
e disponível
y disponible para su uso.
O
 El objeto remoto
é a principal classe gerada pelo
es la principal clase generada por ProxyGen.
java.lang.Objectinstantiate(java.lang.String className)
Instancia
um
un objeto de
uma classe dentro da biblioteca do
una clase dentro de la biblioteca de proxy.
java.lang.ObjecttoProDataGraph(com.datasul.technology.webdesk.dataset.DefaultDataset d)
Transforma
um
un dataset
em um
en un ProDataGraph.