FinnAp XII - Manual Tecnico

Documentación Técnica FinnAp XII Seguimiento de documentación Revisión : 1.0 Documentos relacionados: Lista de distribuc

Views 82 Downloads 0 File size 1MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Documentación Técnica FinnAp XII Seguimiento de documentación Revisión : 1.0 Documentos relacionados: Lista de distribución: Fecha 01/12/2005

Paso Redactor

Ejecutó

Observaciones

Damian Maller

Autorizante 05/05/2008

Modificador

Alejandro Albiero

Perez

Tratamiento Exceptions

Introducción Arquitectura de n-Capas

El Finnegans Application Framework (FAF) esta desarrollado utilizando una arquitectura de n-Capas, lo que nos permite gran versatilidad y escalabilidad. El cliente puede ser tanto un cliente fino (Internet browser) que accede a la aplicación a través de un web Server, como un cliente grueso (Fat client) accediendo directamente al FAF, utilizando los mismos recursos pero en una interfaz rica. El middle tier esta compuesto por el Web Server y por el servidor de aplicaciones. Estas funciones pueden estar albergadas en el mismo equipo o en varios, incluso el servidor de aplicaciones y Web Server, pueden federarse en varios equipos, permitiendo una gran escalabilidad. La capa de datos (Data Server) puede ser cualquier base de datos transaccional (MS Sql Server, Oracle, IBM DB2, etc.) que cumpla con el estándar SQL ANSI 92. Pero el FAF no se detiene allí, sino que también puede interactuar con cualquier data source externo para mostrar o actualizar información y también con cualquier otro sistema (cualquiera sea) a través de un repositorio XML que comparten ambas aplicaciones y es administrado por el framework.

Web Server

El Web Server actua como conector entre el browser y el framework. Para realizar esta función se basa en varios pilares que se ocupan de generar el código HTML (combinado con CSS y funciones de JavaScript) basándose en definiciones abstractas intermedias, almacenadas en XML en el servidor. Esta estructura permite la generación de diferente código, según el cliente que lo acceda y también estar preparado para futuras tecnologías en la presentación de datos.

Soporte Multilenguaje Este modulo es el responsable de la administración de los diferentes lenguajes en el front-end HTML. El framework soporta ilimitada cantidad de lenguajes. Cada lenguaje tiene configurado su diccionario que puede ser modificado en run-time por el usuario de la aplicación. Cada usuario puede ingresar al sistema utilizando su propio lenguaje, es decir que una empresa distribuida globalmente puede permitir a sus usuarios utilizar el sistema en su lenguaje de origen.

DynamicForm Los formularios que utiliza el framework para dar de alta, modificar o eliminar registros es generado dinámicamente en run-time, tomando su estructura de archivo XML que define los elementos de la interfaz (llamados widgets) y su vinculación con una clase de la lógica de negocios. El DynamicForm, permite al implementador o desarrollador realizar cambios en la interfaz sin modificar la lógica de negocios y concentrando su tarea en la resolución del problema. También permite tener múltiples interfaces, personalizada para cada usuario o sector, para una misma entidad en la lógica de negocios. La integridad de los datos nunca es comprometida, ya que estos son controlados por la clase de negocios que administra el formulario y solo son ingresados en la base de datos si están conformes a la lógica de negocios. Otras       

prestaciones destacadas: Soporte de carga de datos múltiples de línea sin recarga de la página Soporte de múltiples solapas Multilenguaje Búsqueda e impresión de registros. Validación de datos en el servidor y en cliente Acciones adicionales Pre-validación y auto-completar de datos

FAFReport Los informes son mostrados al cliente utilizando el FAFreport. Esta herramienta permite manipular la información permitiendo filtrarla, agruparla, ordenarla, graficarla, resumirla, etc. Los esquemas de los informes son almacenados también en formato XML, brindando la posibilidad de realizar cambios al usuario, modificando los filtros, columnas o formatos y dejando esta configuración almacenada, para un uso futuro.

WebParts Las WebParts, son porciones de pantalla que pueden albergar en su interior otros WebParts o algún otro ítem como un FAFReport, un DynamicForm, un link, un grafico, etc. Esta funcionalidad nos permite crear paneles con múltiple información relacionada (por ejemplo Paneles de Control), configurada directamente por el usuario. Los WebParts pueden estar relacionados entre si, para dar información en forma sincronizada.

Widgets Los Widgets son porciones pequeñas de software que tiene como funcionalidad capturar información ingresada por el usuario. Los widgets pueden ser referenciados por otros elementos de la interfaz para crear formularios de ingreso de datos (por ejemplo DynamicForm). Encapsulamiento Al abstraer la creación de los formularios del código fuente HTML, permite crear fácilmente interfaces complejas que pueden ir evolucionando en futuras versiones, enriqueciendo toda la aplicación. Cada widget es responsable de mostrar la información en pantalla, en la superficie que se le asigna y de capturarla nuevamente, una vez que esta es modificada.

Lógica de la aplicación

El framework brinda la estructura y servicios de base a la aplicación que hostea, permitiendo a esta solo focalizarse en el problema a resolver y dejar que el framework resuelva las tareas comunes, como acceso a la base de datos, auditoria de accesos, seguridad, etc.

Facade Es la puerta de entrada a la lógica de negocios de la aplicación y a las herramientas del framework Cada llamada es analizada para determinar si fue solicitada desde un cliente autentificado y si ese cliente tiene permisos suficientes para ejecutar la operación.

Business Logic Layer En la BLL están todas la definiciones e implantaciones de objetos específicos de la aplicación que se esta desarrollando. La separación de la lógica del facade, permite realizar cambios en la BLL sin afectar el contrato con los clientes.

Gestor de Sesiones Cada ingreso a la aplicación es validada por las políticas de seguridad y posteriormente es administrada por el Gestor de sesiones. Este gestor permite determinar los clientes que se encuentran conectados, desconectarlos, crear reglas de permiso de conexión, etc.

Seguridad La seguridad esta basada en roles y prestaciones. El administrador del sistema puede decidir, de manera muy atómica, los permisos que tendrá cada uno de los roles y los usuarios.

FAF Data Engine Para evitar que gran cantidad de información llegue al cliente de manera descontrolada, el framework dispone de un DataEngine que tiene como funcionalidad pedir los datos a una clase determinada y luego cachear y transformar esta información a un formato predefinido (FAFDataset), que contiene solo la información requerida (paginada), ya ordenada, agrupada, sumarizada y con toda la metadata necesaria para que el cliente puede utilizarla directamente.

Personalización El motor de personalización permite a cada usuario guardar el esquema en el cual desea ver la información como así también el estilo de visualización de la misma.

Auditoria Los procesos de negocio son auditados con el nivel de detalle que requiera el administrador del mismo. Esta auditoria permite conocer en detalle que operaciones fueron realizadas por cada usuario en un periodo de fecha determinado.

Gestor de errores Una administración cuidadosa de los errores es muy importante durante el ciclo de vida del sistema. Los errores son calificados en dos tipos: funcionales y operativos Funcionales: Son aquellos errores que son arrojados por el sistema al no cumplirse alguna regla del negocio. Estos errores son predecibles y controlados. Operativos: Son errores que no esperan y que son arrojados por alguna anormalidad en el software o en los sistemas de base (Sistema operativo, hardware, base de datos, etc.)

Messaging Services Estos servicios encapsulan los diferentes servicios de mensajeria (email, SMS, fax, etc) y brindan un modelo único y sencillo de acceder a estos servicios.

Multilenguaje El framework soporta ilimitada cantidad de lenguajes. Cada lenguaje tiene configurado su diccionario que puede ser modificado en run-time por el usuario de la aplicación. Cada usuario puede ingresar al sistema utilizando su propio lenguaje, es decir que una empresa distribuida globalmente puede permitir a sus usuarios utilizar el sistema en su lenguaje de origen.

Detalles Técnicos y de Desarrollo sobre el Framework Introducción La idea de contar con un framework es poder tener una base sólida sobre la cual se puedan montar aplicaciones, sin necesidad de preocuparnos por temas como persistencia de los datos, seguridad, auditoría, soporte multilingüe, campos adicionales, etc. De esta forma, es posible desarrollar aplicaciones complejas de una manera rápida. Como valor agregado, al mejorar el framework, se enriquecen todas las aplicaciones montadas sobre él. El framework está basado en una arquitectura de n-capas, lo que nos permite tener diversos escenarios. Por ejemplo, podemos contar con un servidor de aplicaciones en donde esté la lógica del negocio, un servidor de bases de datos en donde se almacene la información y un servidor web en donde resida la interfaz. El siguiente es un esquema de la arquitectura del Framework.

Plataforma El framework está desarrollado en Java, por lo que es multiplataforma. Para el desarrollo se eligió a Eclipse como IDE de desarrollo, con la extensión de MyEclipse para mayor flexibilidad y poder de desarrollo.

Base de datos El framework está pensado para soportar múltiples bases de datos, para ello la solución provee una serie de herramientas que nos va a permitir acceder a los datos independientemente del motor de base de datos que se esté utilizando.

Diccionario de Datos

Un concepto importante es el del Diccionario de Datos. Mediante el diccionario de datos se podrán definir el mapeo entre una tabla y la clase que la representa y permitirá definir el origen de datos del cual tomará la información. Además será posible agregar campos adicionales en tiempo de ejecución, sin necesidad de tener que recompilar nada, siendo esta una característica muy importante para el desarrollo rápido de aplicaciones, ya que muchos campos serán agregados dinámicamente por un implementador. Cada una de las empresas estará asociada a un origen de datos, de esta manera, se podrá configurar cada entrada en el diccionario de datos dependiendo de la empresa a la que se quiera acceder. Esta abstracción es importante ya que no estamos ligando una prestación a una base de datos en particular, de esta manera, podemos hacer que la empresa apunte a otra base de datos y la aplicación tomará los datos de el nuevo origen sin necesidad de hacer otros cambios. Además es posible tener prestaciones que tomen los datos de diferentes empresas, lo que nos permitiría por ej. Ver un reporte de la empresa A y dentro de la misma aplicación, poder editar los empleados de la empresa B.

Query Builder El mecanismo para efectuar consultas a la base de datos es a través del query builder, ésta es una clase que nos va a permitir componer una sentencia sql para su posterior ejecución sin que nos estemos ligando a un proveedor de base de datos en especial. Éste es un ejemplo de una consulta usando el query builder: import import import import

java.sql.ResultSet; java.sql.Types; java.sql.PreparedStatement; faf.app.base.data.db.iface.QueryBuilder;

dbh = DBHelperManager.getInstance().getDBHelper(session.getEmpresaDatos()); qb = dbh.getNewQueryBuilder(); qb.addField("Codigo"); qb.addField("Nombre"); qb.addTable("Producto"); PreparedStatement prep = qb.getSelectStatement(); ResultSet rs = prep.executeQuery();

FAFDataEngine y FAFDataSet Un FAFDataSet es una abstracción de un Resultset, que nos va a permitir buscar elementos dentro del conjunto de datos, agrupar, sumarizar, paginar, etc. Al crear un FAFDataSet se deberá indicar la clase y el método que conformarán el origen de los datos y luego el FAFDataEngine será el encargado de ejecutar dicho método y llenar de el FAFDataSet. FafDataSetVO dataSet = new FafDataSetVO("faf.client.Tree","getHojas"); dataSet.setSessionID(sessionID); Collection fields = new Vector(); FieldVO fieldID = new FieldVO("ID","system","","ID",true); fields.add(fieldID); FieldVO fieldName = new FieldVO("Nombre","visible","","Nombre ",false); fieldName.setURL("FAF:JAVASCRIPT:opener.document.form1:ID;ID"); fields.add(fieldName); dataSet.setFields(fields); dataSet.execute(); Para obtener más información acerca de ésta o mas clases ver la documentación completa de las clases del framework.

Interoperabilidad El framework permite que las aplicaciones montadas sobre él operen con otros sistemas, sin importar la naturaleza de los mismos. Es decir, podemos construir una aplicación que interactúe con un sistema hecho en Clipper, Visual Basic, C#, Cobol, etc. Y a su vez que resida en un servidor Windows, Unix, una Palm, etc. Hay cuatro modelos de interoperabilidad que describiremos brevemente: 1. 2.

El modelo de Interoperabilidad basado en XML: nuestra aplicación genera un archivo XML con la información que se desea grabar, siendo tarea del otro sistema leer el XML y guardar los datos. Conexión con otros sistemas a través de XML: la comunicación se realiza por medio de web-services utilizando xml para transportar la información.

3. 4.

Conexión directa con bases de datos de otros sistemas: en este método se accede directamente a la base de datos del otro sistema. Interoperabilidad COM: la comunicación se realiza por medio de una dll, que será la encargada de tomar los datos de nuestra aplicación y operar con el sistema en cuestión.

Clientes ricos y finos El framework permite tener diferentes front-ends, de acuerdo a la naturaleza de la aplicación que se esté montando. Un cliente fino, basado en web proporciona una portabilidad insuperable, ya que puede ser accedido desde cualquier pc de escritorio conectada a Internet o bien a una intranet. Sin embargo tiene las limitaciones propias de cualquier aplicación web, y puede no ser la interfaz adecuada para una aplicación con formularios de carga complejos. Un modelo con una interfaz rica, basado en componentes nativos, puede ser la opción para este caso.

Funcionamiento general Round-trip de una llamada al servidor Sesiones de usuarios Seguridad

Componentes del framework Entidades Una entidad representa a un objeto que queremos que se guarde en la base de datos. Si en nuestra aplicación necesitamos, por ejemplo, manejar productos, nos bastará con crear una entidad Producto utilizando las clases que provee el framework para que, de esta manera, heredemos la funcionalidad general a cualquier entidad, como crear, modificar, eliminar, seguridad, auditoría, etc. El framework provee una jerarquía de herencia que nos va a permitir construir nuevas entidades de una manera rápida y sencilla. El siguiente es un diagrama con las principales clases a tener en cuenta: PrimaryKey

TransaccionVO

EntidadVO

EntidadPrimariaVO

AtributoVO

EntidadSecundariaVO

ForeignKeyVO

ParentVO

EntidadHLP

EntidadVO: Es la clase que se encarga de mapear la estructura de la tabla en la base de datos con la representación en Java. Básicamente definirá a los atributos junto con las operaciones para acceder a los mismos. PrimaryKey: Es una abstracción de una PrimaryKey. AtributoVO: Esta clase sirve para representar a un atributo de la entidad.

EntidadPrimariaVO: Esta clase define Código,Nombre,Descripción y Activo.

algunos

atributos

que

son

generales

para

cualquier

entidad,

como

TransaccionVO: Define atributos propios de una transacción, como Fecha, Número Interno, Comprobante, Observaciones, etc. EntidadSecundariaVO: Se utiliza para representar listas de entidades que formarán parte de otras entidades. Por ejemplo si tenemos la clase Persona y queremos asociarle una lista de teléfonos, debemos definir la clase TelefonoVO como una entidad secundaria. ParentVO: Se utiliza para vincular a la entidad secundaria con la entidad primaria que la contiene. EntidadHLP: Es la otra clase clave en el modelo. Se encarga de operar sobre las entidades, e implementará las operaciones para crear, modificar, borrar, buscar, etc. Para crear una entidad sencilla, por ejemplo Provincia, es necesario construir dos clases: ProvinciaVO y ProvinciaHLP. ProvinciaVO definirá el mapeo de la clase con la estructura de la tabla, mientras que la clase helper ProvinciaHLP tendrá los métodos que trabajan sobre los datos, como por ejemplo, buscar, crear, modificar, listar, etc. Siempre que hablemos de una entidad tenemos que tener presentes estas dos clases, la clase VO y la clase Helper. Por ejemplo, para construir la clase ProvinciaVO deberíamos hacer algo como: public class ProvinciaVO extends EntidadPrimariaVO implements Serializable { public ProvinciaVO(String sessionID) throws FunctionalException { //Se envia el identificador de la pk y el nombreFisico super("ProvinciaID", "Provincia", sessionID); try { atributosPropios.add(new AtributoVO(20,"PaisId", "Pais", new FafInteger(), "", true, new ForeignKeyVO("PaisID", "Nombre", "Pais"),false, true)); } catch (Exception e) { ExceptionUtil.write(e); throw new FunctionalException(); } } . . . Nótese que el método constructor deberá recibir el identificador de la sesión en curso. Se deben generar así mismo, los correspondientes métodos setters y getters para la clase en cuestión, dichos métodos son utilizados para interactuar con los atributos propios de la clase definidos previamente. . . . public Integer getPaisId() { return Integer.valueOf( atributosPropios.getAtributo("PaisID").getValor().toString()); } public ForeignKeyVO getPais() { return atributosPropios.getAtributo("PaisID").getForeignKey(); } public String getPaisNombre() { return atributosPropios.getAtributo("PaisID").getForeignKey().getNombre(); } public void setPaisId(Integer newId) { try { atributosPropios.setAtributo("PaisID", newId); } catch (Exception e) { ExceptionUtil.write(e); } } public void setPaisNombre(String newNom) { try { AtributoVO atrib = atributosPropios.getAtributo("PaisID"); ForeignKeyVO fk = atrib.getForeignKey(); fk.setNombre(newNom); atrib.setForeignKey(fk); atributosPropios.setAtributo("PaisID", atrib);

} catch (Exception e) { ExceptionUtil.write(e); } } . . . Ahora bien, supongamos que estamos construyendo la entidad Persona y deseamos que tenga una lista de teléfonos. Para ello necesitamos crear la entidad Teléfono, pero la definiremos como una entidad secundaria. public class TelefonoVO extends EntidadSecundariaVO implements Serializable { public TelefonoVO(String sessionID)throws FunctionalException { super(null, "Telefono", sessionID, new ParentVO("PersonaID", "Persona", "PersonaID")); try { atributosPropios.add(new AtributoVO("PersonaID", FafInteger(),true, false, true));

"PersonaID",

new

atributosPropios.add(new AtributoVO("Numero", "Numero", new FafString(20), true, true, true)); atributosPropios.add(new AtributoVO("Categoria", "Categoria", new FafString(100), true, true, true)); } catch (Exception e) { ExceptionUtil.write(e); throw new FunctionalException(); } }

Facade La interacción entre el framework y los “clientes”, se realiza a través del facade o los facade, es decir los facade son la puerta de entrada al framework, siendo necesario para un correcto funcionamiento que el facade defina los métodos necesarios para “negociar”, con los “clientes”. Aquí representaremos con un ejemplo sencillo como agregar un nuevo método al “facade”, teniendo especial cuidado en esta etapa, dado que el facade se compone de 3 archivos. Ahora bien, supongamos para nuestro ejemplo que deseamos agregar un método al facade que nos devuelva la suma de 2 cantidades enteras. Es decir definiremos el método suma(int a, int b) : int Un bean en este caso se compone de los siguientes archivos. ejb-jar.xml - Xml de configuración del bean. NombreBeanEJB.java -Definición de los métodos NombreBeanEJBBean.java -Implementación de los métodos. NombreBeanEJBHome.java -Inteface Home del Bean.

1) Archivo ejb-jar.xml Un ejemplo de dicho archivo puede ser el siguiente:



Session Bean ( Stateless ) NombreBeanEJB NombreBeanEJB faf.app.resources.facade.NombreBeanEJBHome faf.app.resources.facade.NombreBeanEJB faf.app.resources.facade.impl.NombreBeanEJBBean Stateless Container



2) Archivo NombreBeanEJB.java Dicho archivo es la interfaz remota, es donde definimos los métodos que se dejarán acceder por los clientes, es decir que en nuestro ejemplo aquí deberíamos agregar una línea como la siguiente:

int suma(int a, int b) throws RemoteException;

3) Archivo NombreBeanEJBBean.java Dicho archivo es donde implementamos los métodos que previamente agregamos en el archivo de interfaz, en nuestro caso agregaríamos una definición del método suma de la siguiente manera:

public int suma(int a, int b) throws RemoteException{ return a+b; }

4) Archivo NombreBeanEJBHome.java Dicho archivo es la interfaz home de la bean, es donde se tienen los métodos que son propios de la bean tales como create. Es decir en dicho archivo se pueden encontrar métodos como el siguiente:

NombreBeanEJBcreate() throws RemoteException, CreateException;

Sesiones Modelo de sesiones Tiempo de vida Encriptación

Seguridad El framework provee un modelo de seguridad por prestaciones basado en usuarios y roles. Un usuario puede pertenecer a uno o mas roles. De esta manera, es posible, para una prestación dada, asignar permisos a algunos usuarios en particular o bien a uno o más roles. Existen cuatro políticas de seguridad básicas:  Para consultar información (Select).  Para dar de alta datos (Insert).  Para modificar datos (Update).  Para eliminar información (Delete). Existe un requisito a la hora de nombrar a las prestaciones, y es que el nombre debe estar compuesto por el nombre de la tabla seguido del nombre de la política de seguridad que se desea implementar. Por ejemplo, para definir la prestación Insert de la tabla vLaboreo, es necesario crear una nueva prestación con el nombre: ‘vLaboreo.insert’.

Auditoria Seguimiento de una transacción Modelo de datos

Errores Diferentes tipos de errores Manipulación de errores

Multilenguaje Códigos de lenguaje Como manipular los mensajes del framework en multiples lenguajes Creación de nuevos mensajes

Interfaz del usuario Abstrayendo la interfaz del usuario de su implementación Soporte para customización de la aplicación Personalización de formularios e informes Estructura de formularios Estructura de informes AppItems: tipos, estructura de datos

Framework Web Introducción Arquitectura global Manejo de estilos a través de CSS

Multilenguaje Mensajes propios de la UI son administrados por el framework Web Manejos de lenguaje en formularios, informes y paginas ad hoc

Widgets Un widget es una abstracción de un componente de una ventana. Actualmente tenemos implementados los siguientes widgets:           

WidgetButton WidgetTextBox WidgetCheckBox WidgetSelectBox WidgetMemo WidgetFecha WidgetSelector WidgetLine WidgetButtonServerAction WidgetPassword WidgetSelectorTree

Un widget puede tener diferentes implementaciones, por ejemplo, puede tener una implementacion HTML y otra utilizando AWT, pero la idea es que a un widget siempre le vamos a poder asignar o pedir su valor. A su vez, un widget puede tener acciones asociadas, que servirán para efectuar las validaciones que sean necesarias del lado del cliente. Las propiedades mas comunes de los widgets son las siguientes: Propiedad

Descripción

Name

Es el nombre que le vamos a dar al widget

Type

Tipo de widget

ClassProperty

Identifica al atributo de la entidad

JavaType

Es el tipo de datos Java con el que se representa el valor del widget

Visible

Indica si el widget es visible

ReadOnly

Indica si el widget es de solo lectura

Required

Indica si el widget es requerido

Cols

Numero de columna

Rows

Numero de fila

Caption

Especifica el titulo del widget, el mismo tiene soporte multilenguaje

OnEnter

Acción que se ejecutará cuando se hace foco en el widget

OnExit

Acción que se ejecutará cuando se pierde el foco del widget

Value

Valor del widget

FillMethodType

En el caso de los selectores es 1, para los combos 2

FillMethodOptions

En los selectores es el método que se ejecuta para obtener los datos

ExtraProperties

En el caso de los selectores es el codigo de la entrada en el diccionario de datos del selector que se desea ver.

Ahora vamos a ver una definición XML correspondiente a un widget cualquiera, para ver cuales son las propiedades comunes que tienen, y analizar su uso. Un widget no necesita estar representado por un XML, pero este ejemplo nos será útil mas adelante, para definir formularios basados en widgets, en el que sí estarán definidos por un XML.

Definición XML de un widget.

DynamicForm Para implementar un formulario el framework nos provee del DynamicForm. El DynamicForm toma una definición de un XML y genera una interfaz basada en solapas y widgets. El DynamicForm es esencial cuando queremos implementar la interfaz para un ABM, en este caso la definición del XML se asemeja a un mapeo de los atributos de la entidad con la que estamos trabajando, es decir, cada uno de los widgets de la intefaz corresponderá a un atributo de la entidad. En este caso podríamos hablar de un EntityForm (Los términos DinamicForm y EntityForm se utilizarán indistintamente cuando estemos hablando de DinamicForms de entidades), sin embargo, un DinamicForm no necesariamente tiene que estar ligado a una entidad, por lo que se transforma en una herramienta poderosa para crear páginas adhoc con la simple definición de un XML. En el caso de un EntityForm, tendrá asociada una Toolbar con las acciones típicas que se pueden aplicar sobre una entidad. Además existe la posibilidad de agregar acciones adicionales.

Ahora veamos un ejemplo de un formulario de la entidad Laboreo basado en el DynamicForm:

Formulario de Laboreo. Ver definición del XML Ahora veamos como construir una interfaz de una entidad más sencilla, como por ejemplo una Máquina. Para ello, comenzaremos por definir el encabezado del XML:

> El atributo library sirve para indicar cual va a ser la librería que manejará la lógica del formulario. OnInit indica la rutina que se ejecutará al cargar el formulario. Ahora definiremos una solapa

Y agregamos nuestro primer widget, que representa la primarykey de la entidad:

Ahora agregamos un widget para definir el código:

de la misma manera definimos los widgets para el código, activo y descripción, finalmente, cerramos los tags de la solapa y el formulario:



El resultado es la siguiente interfaz:

El EntityForm también permite generar un HTML con formato imprimible, presionando el botón Imprimir desde la toolbar. Por Ejemplo:

Impresión de un Laboreo. Pintado del dinamicForm DinamicForm.js

editor.jsp

Toolbar

DinamicFormVO

XMLParser

DinamicForm.java

ActionRefresh

Tab

Widget

openWindowInLine Crea Obtiene parse(xml) execute doIt getHTML *getHtml *getHtml

Hago una llamada ajax al editor jsp, pasandole la acción "refrescar"

Recorro los Tabs y genero su codigo html

Ejecuto el ActionRefresh, para obtener los datos de la entidad y llenar los widgets Genero el html del dinamicForm, pasandole la toolbar y el model creados

Recorro y genero los htmls de los widgets del Tab

FAFReport El FAFReport o WebReport, provee la implementación HTML de una grilla, y se usa principalmente para generar reportes o para listar ítems antes de su edición. El FAFReport puede utilizar una definición XML para dar formato a la vista. En esta definición se pueden establecer las columnas a mostrar, el título de las columnas (soporta multilenguaje), las agrupaciones, sumarizaciones, gráficos, etc. Por ejemplo, una definición sencilla sería:













Y el FAFReport resultante es:

Ejemplo del FAFReport de Establecimientos. El ejemplo de arriba muestra un listado de establecimientos. Observemos que existen dos barras de herramientas. Veamos las opciones de la barra superior.

En la barra inferior, se muestran las acciones adicionales, configuradas en el AppItem. Como en este caso estamos listando una entidad, automáticamente aparecen las acciones de Borrar y Nuevo. Además si el FAFReport lista entidades, se mostrarán checks para poder marcar varias filas, y de esta forma, ejecutar acciones sobre varias entidades. Si observamos nuevamente el FAFReport, podemos ver que el nombre del establecimiento es un link, al entrar al mismo nos conduce al EntityForm asociado:

Al imprimir, se mostrará un reporte Jasper generado dinámicamente.

Reporte del FAFReport de Establecimientos. También es posible ver el gráfico asociado, siguiendo el ejemplo, podemos ver la superficie por establecimiento:

Gráfico del FAFReport. También es posible realizar agrupaciones y sumarizaciones dentro de un FAFReport. Para ello es necesario modificar la definición del XML indicando los grupos y por que campo se desea sumarizar:





Además es posible agregarle parámetros al FAFReport, para poder filtrar los datos a mostrar. Los parámetros se deben configurar en la definición del AppItem. Veamos un ejemplo:

FAFReport con agrupaciones y parámetros. Ya hemos repasado gran parte de la funcionalidad del FAFReport, pero de donde toma los datos? Por debajo de un FAFReport siempre hay un FAFDataSet que mantiene los datos a mostrar. Entonces cuando configuramos el AppItem, tendremos que indicar cual es el método que se invocará para llenar dicho FAFDataSet y alimentar al FAFReport.

Explotación de grillas Es posible definir que, al hacer clic sobre una grilla de un webReport, la aplicación se dirija a una vista de destino pasándole automáticamente: 1)

Los parámetros (junto a sus valores) de la vista de origen.

2)

Los valores de ciertos campos de fila de la grilla sobre la cual se hizo clic. Dichos campos son definidos por el usuario, junto al nombre con el cual desea que cada uno de ellos llegue a la vista de destino.

La vista de destino recibirá estos parámetros. En caso de que la misma posea parámetros con el mismo nombre de los enviados, entonces los parámetros de esta vista adquirirán el valor de los parámetros pasados desde la vista de origen. Veamos un ejemplo de definición de XML de webReport:







. . . Etc.

width="0"

order="6"

caption="Cliente"

Lo importante aquí son dos cosas, las cuales en el ejemplo están marcadas en negrita: 1) El atributo “linkedView” del tag “root”, el cual indica el id de la vista a la cual la aplicación se dirigirá al hacer clic sobre una fila de la grilla. 2) El atributo “linkedParameter” en cada uno de los fields cuyo valor deseamos trasladar a la vista de destino. El valor de este atributo será el nombre del parámetro de la vista de destino para el cual queremos que tome como valor el valor de este field.

Vincular un webReport a un datasource distinto al de la empresa logueada Si tenemos una grilla que se llena en base a un SP, por default dicho SP será buscado y ejecutado en el datasource definido para la empresa logueada (según lo indique el archivo \jboss\server\default\deploy\ mssql-ds.xml). Es posible también buscar y ejecutar el SP en un datasource distinto. Para ello, debemos crear una entrada en el diccionario de datos cuyo campo “Nombre clase” coincida exactamente con el campo “Método” de la view. Veámoslo mediante un ejemplo. Supongamos que tenemos la siguiente view:

Si no creamos una entrada en el diccionario de datos, el SP “SP_Presupuestos” será buscado y ejecutado en el datasource de la empresa logueada. Para definir un datasource distinto, deberemos creer una entrada en el diccionario de datos como por ejemplo la siguiente:

Lo importante aquí es que el campo “Nombre clase” de la entrada del diccionario de datos coincida con el campo “Metodo” de la view. De este modo, según el ejemplo, el SP será buscado y ejecutado en el origen de datos “BSA2”. Como puede apreciarse, no es necesario definir una referencia a un diccionario de datos determinado en la view, como así tampoco es necesario definir el campo “Nombre Tabla” en el diccionario.

Web Chart Este proyecto se encarga de la generación de gráficos. Para la impresión de los gráficos se utilizan objetos flash, provistos por www.fusioncharts.com La clase principal de éste módulo es FAFChart, que implementa el método getHtml, que dado un FAFDataset y las columnas a graficar, devuelve el código html del gráfico generado. FafChart

FactoryCharts +

getChart(String) : FafChart

-

titulo: String request: HttpServletRequest ancho: int alto: int dataset: FafDataSetVO = null column1: String column2: String

+* + + # # + + + + + + + + + + + + + +

getHtml(FafDataSetVO, String, String, int, int) : String getHtml() : String getDetalle(FafDataSetVO, String) : String getValues(FafDataSetVO, String, String) : HashMap getColor() : String getTitulo() : String setTitulo(String) : void getRequest() : HttpServletRequest setRequest(HttpServletRequest) : void getAlto() : int setAlto(int) : void getAncho() : int setAncho(int) : void getColumn1() : String setColumn1(String) : void getColumn2() : String setColumn2(String) : void getDataset() : FafDataSetVO setDataset(FafDataSetVO) : void

PieChart3D +

AreaChart

getHtml(FafDataSetVO, String, String, int, int) : String +

getHtml(FafDataSetVO, String, String, int, int) : String

PieChart BarChart +

getHtml(FafDataSetVO, String, String, int, int) : String +

LineChart +

Contenido Web

getHtml(FafDataSetVO, String, String, int, int) : String

getHtml(FafDataSetVO, String, String, int, int) : String

BarChart3D +

getHtml(FafDataSetVO, String, String, int, int) : String

La función de este módulo es la de mostrar contenidos (artículos, notas, videos de youTube, blogs, etc) Los contenidos se administran a través de la clase ContenidoVO y ContenidoHLP de openFrame, y se almacenan en las tablas FAFContenido, FAFContenidoArchivos y FAFContenidosRelacionados. Existe además el concepto de Canal que identifica a una view de tipo ContentView. Los contenidos se asocian a un canal principal y a posibles canales relacionados. Por ejmplo, podemos tener un Contenido que sea una noticia, que esté asociado a un canal “novedades home” y a los canales “novedades Ceres” y “novedades Agropuerto”. Los contenidos se cargan desde el administrador de contenidos, cuando se guardan, se genera un xml con la información de dicho contenido y se guarda en un campo de la tabla FAFContenido. Ya que la visualización de un contenido, es muy dinámica y depende del tipo de contenido que se está mostrando, estilos del sitio, etc. se utiliza un XSLT para transformar el xml que representa al contenido (el que se guarda en el campo de FAFContenido) en código HTML. Este XSL se configura en el xml de la vista (o canal) correspondiente. Se utilizan dos XSL, uno para mostrar un contenido en forma completa (la noticia entera) y otro para mostrar una lista de contenidos (TOP 5 de noticias por ej)

Indicador Web Los Indicadores (gauges) son componentes gráficos que permiten mapear un valor dentro de una escala definida. La implementación es bastante parecida a la de los gráficos, y se utiliza una solución provista por el mismo fabricante www.fusioncharts.com La clase IndicadorVO (Framework) representa a la entidad indicador, que se mapea con la tabla FAFIndicador. Básicamente lo que definimos en el indicador es indicar un mecanismo para obtener un valor, que luego se mapeará en una escala. Cuando definimos el indicador, podemos decir que el valor del mismo estará dado por una constante, la ejecución de un método, o un stored procedure. En el caso de que se trate de éstos dos últimos, se podrán indicar parámetros.

Cuando se define una view de tipo Gauge, se debe indicar que indicador tendrá asociado. Hay tres tipos de indicadores: Velocímetros, Semáforos y Termómetros. Una view de tipo Indicador, tiene un xml de configuración asociado a la vista, donde se configuran las escalas, el tipo de indicador a mostrar, etc. Un ejemplo de un xml para una vista de tipo indicador es:



Valor_Estandar





model::EscalaVO

Indicador + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -

Indicador(IndicadorVO) getAplicacion() : String setAplicacion(String) : void getConfig() : HashMap setConfig(Collection) : void isAutoRefresh() : boolean setAutoRefresh(boolean) : void getEmpresa() : String setEmpresa(String) : void getEscalas() : Collection setEscalas(Collection) : void getFacade() : Object setFacade(Object) : void getFormDefinition() : String setFormDefinition(String) : void getFormName() : String setFormName(String) : void getIdioma() : String setIdioma(String) : void getSessionID() : String setSessionID(String) : void getSessionIDExterna() : String setSessionIDExterna(String) : void getUserLogicViewList() : HashMap setUserLogicViewList(HashMap) : void getUserViewList() : Collection setUserViewList(Collection) : void getViewID() : String setViewID(String) : void getHashRequest() : HashMap setHashRequest() : void getOutput() : PrintWriter setOutput(PrintWriter) : void getRequest() : HttpServletRequest setRequest(HttpServletRequest) : void getResponse() : HttpServletResponse setResponse(HttpServletResponse) : void getHtml() : String getData() : HashMap setData(Collection) : void

+ + + + + + +

getImage() : String setImage(String) : void getNombre() : String setNombre(String) : void getStatus() : String setStatus(String) : void compareTo(EscalaVO, EscalaVO) : Integer

+ + + + + + + + + + + + + + + + + + + +

IndicadorVO(String, String, Object, PrintWriter, HttpServletRequest, HttpServletResponse, String) IndicadorVO(String, String, Object, PrintWriter, HttpServletRequest, HttpServletResponse, String, Collection, HashMap) setFormName(String) : void setInputStream(String) : void setFacade(Object) : void setPrintWriter(PrintWriter) : void setRequest(HttpServletRequest) : void setResponse(HttpServletResponse) : void setSessionID(String) : void setUserViewList(Collection) : void getFormName() : String getInputStream() : String getFacade() : Object getPrintWriter() : PrintWriter getRequest() : HttpServletRequest getResponse() : HttpServletResponse getSessionID() : String getUserViewList() : Collection setUserLogicViewList(HashMap) : void getUserLogicViewList() : HashMap

model::IndicadorVO *

1

helper::IndicadorHLP + + + +

setFormDefinition(String) : void getFormDefinition() : String getIndicadorData(FAFContentEJB, HttpServletRequest, HttpServletResponse, String, PrintWriter, long) : IndicadorVO processException(HttpServletRequest, PrintWriter, Exception) : void

Gauge -

escala: EscalaVO valor: String escalas: Collection statusColor: HashMap config: HashMap

+ +* + + + + + + # # + + + +

Gauge(String, Collection, HashMap) getHtml() : String getEscala() : EscalaVO setEscala(EscalaVO) : void getEscalas() : Collection setEscalas(Collection) : void getValor() : String setValor(String) : void getMax() : long mapearValorEnEscala(String) : EscalaVO getEscalasByStatus(Collection, String) : Collection ordenarEscalas(Collection, boolean) : Collection getStatusColor(String) : String getConfig() : HashMap setConfig(HashMap) : void

Velocimetro

Semaforo

Termometro + + -

Velocimetro(String, Collection, HashMap) getHtml() : String getXmlVelocimetro() : String

+ + -

Termometro(String, Collection, HashMap) getHtml() : String getXmlDatos() : String

+ + -

Semaforo(String, Collection, HashMap) getHtml() : String getXml() : String

Al momento de mostrar una view de tipo Gauge, lo que se hace es:   

parsear el xml de la vista, para obtener la configuración de las escalas, tipo de gauge, etc. Obtener el valor asociado al indicador, desde el método, sp u constante correspondiente. Obtener una instancia del gauge correspondiente (Velocímetro, Semáforo, Termómetro) y llamar al método para pintarlo, pasandole el valor a mapear y las escalas.

Diccionario de Datos - Campos adicionales Seguir los siguientes pasos para agregar un campo adicional: 1. 2. 3.

Definir la entrada de tipo clase en el diccionario de datos, indicando: clase VO, nombre de tabla, origen de datos y los atributos adicionales. Agregar el campo a la tabla por SQL. Agregar el widget al XML usando el nombre del campo como classProperty.

JasperReports El FAFReport es una alternativa para mostrar reportes, sin embargo puede haber algunos casos en el que se necesite mas poder a la hora de generar un reporte, como por ejemplo, la impresión de un balance. Para ello es posible armar un reporte utilizando la herramienta Jasper Reports e invocarlo desde la aplicación. El formato de este tipo de reportes queda almacenado en un XML, que puede generarse utilizando alguna herramienta para editar reportes Jasper, como por ejemplo iReport© o Jasper Assistant©. Estos reportes tomarán los datos desde un CustomDatasource, de esta manera será posible mostrar información que está almacenada en una base de datos, un archivo XML, etc. Veamos un ejemplo de cómo implementar un reporte sencillo, para ello es necesario definir una clase que obtenga los datos a mostrar.

package app.ceres.reportes; import import import import import import import import import import import import

java.sql.ResultSet; java.sql.*; faf.app.base.security.session.SessionHLP; faf.app.base.security.session.model.SessionVO; java.util.Collection; java.util.Hashtable; java.util.Map; java.util.Vector; faf.app.base.data.db.DBHelperManager; faf.app.base.data.db.iface.DBHelper; faf.app.base.data.db.iface.QueryBuilder; faf.app.base.exceptions.FunctionalException;

public class EstablecimientosDS { private SessionVO session=null; private Map params = null; public EstablecimientosDS(String sessionID, Map FunctionalException{ this.session = SessionHLP.getSession(sessionID); this.params = parameters; }

parameters)

throws

public Collection getData() throws FunctionalException{ ResultSet rs=null; Collection datos =null; try { DBHelper dbh = null; dbh DBHelperManager.getInstance().getDBHelper(session.getEmpresaDatos()); QueryBuilder qb = dbh.getNewQueryBuilder(); PreparedStatement ps; qb.addField("LF_ID"); qb.addField("Nombre"); qb.addField("Codigo"); qb.addTable("vEstablecimiento");

=

ps = qb.getSelectStatement(); rs = ps.executeQuery(); datos = new Vector(); for (;rs.next();){ Hashtable registro = new Hashtable(); for (int i=1;i





Fields Los Report Fields sirven para mapear los datos desde el data source en el reporte. Ejemplo: Para los siguientes datos:

Column Name Datatype Length -------------------------------------EmployeeID int 4 LastName varchar 20 FirstName varchar 10 HireDate datetime 8

Página 53 de 57

Podemos definir los siguientes fields en el reporte:

Expressions Las Expressions son Java Expressions que son usadas para declarar variables del reporte que sirven para ejecutar calculos, por ejemplo para un Data Group en el reporte, etc. Hay varios elementos que definen las Expresiones: , , , , and .

Ejemplo:

$F{FirstName} + " " + $F{LastName} "Total quantity : " + $V{QuantitySum} + " kg."

Variables

$F{Quantity} new Double(0)

Existen varias variables built-in del sistema listas para usar sin definir en el reporte: PAGE_NUMBER COLUMN_NUMBER REPORT_COUNT PAGE_COUNT COLUMN_COUNT GroupName_COUNT

Report Sections Existen las siguientes seccines: , , , .

,

,

,

,

,

Ejemplo:

Página 54 de 57







Northwind Order List



Groups



...

...

Página 55 de 57

Documentación Técnica FinnAp XII.................................................................................................................1

Seguimiento de documentación.........................................................................................................................................1

Introducción.............................................................................................................................................2

Arquitectura de n-Capas..................................................................................................................................................2 Web Server...............................................................................................................................................................3 Soporte Multilenguaje..................................................................................................................................................3 DynamicForm............................................................................................................................................................3 FAFReport.................................................................................................................................................................4 WebParts..................................................................................................................................................................4 Widgets................................................................................................................................................................... 4 Lógica de la aplicación....................................................................................................................................................5 Facade....................................................................................................................................................................5 Business Logic Layer....................................................................................................................................................5 Gestor de Sesiones......................................................................................................................................................6 Seguridad.................................................................................................................................................................6 FAF Data Engine.........................................................................................................................................................6 Personalización..........................................................................................................................................................6 Auditoria..................................................................................................................................................................6 Gestor de errores........................................................................................................................................................6 Messaging Services......................................................................................................................................................6 Multilenguaje............................................................................................................................................................6

Detalles Técnicos y de Desarrollo sobre el Framework........................................................................................7

Introducción................................................................................................................................................................7 Plataforma................................................................................................................................................................7 Base de datos............................................................................................................................................................7 Diccionario de Datos.................................................................................................................................................8 Query Builder..........................................................................................................................................................8 FAFDataEngine y FAFDataSet........................................................................................................................................8 Interoperabilidad........................................................................................................................................................8 Clientes ricos y finos....................................................................................................................................................9 Funcionamiento general...............................................................................................................................................9 Componentes del framework............................................................................................................................................9 Entidades.................................................................................................................................................................9 Facade...................................................................................................................................................................11 1) Archivo ejb-jar.xml.................................................................................................................................................11 2) Archivo NombreBeanEJB.java....................................................................................................................................12 3) Archivo NombreBeanEJBBean.java..............................................................................................................................12 4) Archivo NombreBeanEJBHome.java.............................................................................................................................12 Sesiones.................................................................................................................................................................12 Seguridad................................................................................................................................................................12 Auditoria................................................................................................................................................................13 Errores...................................................................................................................................................................13 Multilenguaje...........................................................................................................................................................13 Interfaz del usuario....................................................................................................................................................13 Framework Web...........................................................................................................................................................13 Introducción............................................................................................................................................................13 Multilenguaje...........................................................................................................................................................13 Widgets..................................................................................................................................................................14 DynamicForm...........................................................................................................................................................15 FAFReport...............................................................................................................................................................18 Explotación de grillas....................................................................................................................................................21 Vincular un webReport a un datasource distinto al de la empresa logueada................................................................................22 Web Chart...............................................................................................................................................................23 Contenido Web.........................................................................................................................................................23 Indicador Web..........................................................................................................................................................24 Diccionario de Datos - Campos adicionales........................................................................................................................26 JasperReports..........................................................................................................................................................27 AppItems................................................................................................................................................................28

Página 56 de 57

WebPart.................................................................................................................................................................... 31 Construcción de paginas Adhoc......................................................................................................................................34 Construcción de aplicaciones (workshop)............................................................................................................................34 Especificación de implementación ABM...............................................................................................................................34 Descripción breve......................................................................................................................................................34 Flujo de Acciones......................................................................................................................................................34

Tratamiento de Exceptions.........................................................................................................................42

Introducción...............................................................................................................................................................42 Templates de Exceptions para código JAVA........................................................................................................................42 Templates de Exceptions para código JSP..........................................................................................................................43 Templates de Exceptions para código JavaScript................................................................................................................45 Mensajes Funcionales en JavaScript................................................................................................................................45 Llamadas AJAX.........................................................................................................................................................45

JasperReports.........................................................................................................................................47

Introducción...............................................................................................................................................................47 Requerimientos.........................................................................................................................................................47 Funcionamiento........................................................................................................................................................47 Instalación..............................................................................................................................................................48 iReports..................................................................................................................................................................49 Requerimientos:.........................................................................................................................................................49 Instalacion:...............................................................................................................................................................49 Ejemplos:.............................................................................................................................................................50 Definición XML:..................................................................................................................................................- 53 Elementos:........................................................................................................................................................- 53 -

Página 57 de 57