Diferencia entre revisiones de «Contenedores»
(→Atributo {{AT|grupo}}) |
(→Atributo {{AT|grupo}}) |
||
Línea 493: | Línea 493: | ||
... | ... | ||
{{PR|fin}} | {{PR|fin}} | ||
+ | |||
+ | <p>Ahora, si accedemos al egExplorer y entramos a la colección donde están incluídas las definiciones agrupadas, veremos lo siguiente: | ||
+ | |||
+ | |||
[[Categoría:ODL]] | [[Categoría:ODL]] | ||
[[Categoría:Definiciones]] | [[Categoría:Definiciones]] | ||
[[Categoría:Recursos]] | [[Categoría:Recursos]] |
Revisión del 11:23 8 jul 2009
Contenido
¿Qué es un contenedor?
Un contenedor es un recurso fundamental de ODL que nos permite crear objetos en un sistema de información.
Pero, ¿y qué función cumplen los objetos en ODL?
Su principal función es representar aquellos elementos o conceptos físicos que intervienen en el sistema de información de una organización. Elementos tales como fichas, ficheros, informes, registros, oficinas, etc., son ejemplos de elementos que puede generar un sistema de información y que podrán ser representados en ODL.
¿Qué definiciones podemos realizar?
En ODL, existen dos formas de definir un contenedor:
Definiciones de tipo
Una definición de tipo nos permite crear objetos en un sistema de información. Es un concepto basado en POO, donde se define una clase con su posterior creación de objetos u otras clases derivadas.
La estructura del objeto vendrá definida, valga la redundancia, en la definición de tipo. Formularios, secciones o campos son algunos de los componentes que podremos incluir en la definición y que nos permitirán introducir la información que almacenará el objeto. Una vez creado el objeto, podrá ser editado o eliminado por el usuario, siempre y cuando tenga los permisos necesarios para poder realizar dichas operaciones.NOTA: Existen varios casos en los que un objeto no puede ser eliminado:
- Si un objeto tiene un campo timbre o firma, y el campo timbre está timbrado o el campo firma está firmado, el objeto no se podrá eliminar.
- Otra posibilidad que se puede dar es que un objeto puede estar "apuntado" por otros objetos mediante un campo vínculo. En este caso, tampoco se podría eliminar el objeto.
- El último caso está relacionado con el workflow del sistema de información. Si un objeto es el target de alguna tarea, y ésta no ha sido abortada, dicho objeto tampoco podrá ser eliminado.
- También hay que tener en cuenta los roles que tenga asignados el usuario, ya que en al menos uno de ellos debe tener incluído el siguiente permiso: accede [Definición de contenedor]: crear;. Este permiso permite al usuario crear, modificar, abrir o eliminar un objeto de la definición en cuestión. Los permisos abrir o eliminar no permite eliminar objetos.
Definiciones de sistema
Una definición de sistema permite crear objetos al crear un centro. Los objetos creados en la instalación de un centro los denominaremos objetos de sistema.
Aunque en ODL se puede definir cualquier componente en un contenedor, en los objetos de sistema normalmente se suele utilizar la componente colección para realizar visualizaciones de objetos, o, en su defecto, catálogos. Estos componentes nos permitirán realizar visualizaciones personalizadas de los tipos de objetos que se desee, especificando la información a mostrar. A diferencia de las definiciones de tipo, el usuario no podrá crear, modificar o eliminar los objetos de sistema; será una tarea exclusiva del programador.Veamos un ejemplo
Vamos a realizar un sencillo ejemplo de forma que podamos reflejar en un caso práctico los conceptos anteriormente explicados.Imaginemos que tenemos una estantería vacía. Y en esa estantería iremos insertando libros con el transcurso del tiempo. Veamos pues como podemos trasladar este caso a lenguaje ODL usando contenedores.
¿Cómo implementamos una definición de tipo?
Como ya hemos dicho, ODL nos ofrece una serie de componentes que podremos utilizar en la definición de un tipo contenedor. Los componentes más comunes son formularios, secciones y campos.
Un campo es la unidad más básica para la introducción de datos. Una sección es un conjunto de campos y un formulario es un conjunto de secciones y campos. Éstos nos permitirán introducir la información relativa a un objeto.
Por tanto, para el concepto de Libro realizaremos una definición de tipo, usando los componentes antes mencionados, que nos permitirá crear un objeto por cada libro que insertemos en la estantería:
Nuestra definición de tipo ya está creada. Como podrás observar, hemos definido un formulario dentro del contenedor, que a su vez contiene varios campos y una sección que nos va a permitir introducir la información perteneciente a cada libro. Existe un campo timbre que se utiliza para autonumerar, en este caso, los libros que vayamos registrando. Los demás campos son todos de tipo texto.tipo
[Libro]es
contenedor
[Datos]es
formulario
[Código]es
timbre
-certificado
.valor
= [&Valor_secuencia]; -certificado
.secuencia
.nombre
="STR$LIBRO"
; -certificado
.secuencia
.longitud
= 4; [Título]es
texto
[Autor]es
texto
[Edición]es
texto
[Editorial]es
texto
[Contenido]es
seccion
[Tipo]es
texto
-edicion.valores
= $Matriz("Literario"
,"Biografía"
,"Científico"
,"Infantil"
); -apariencia.desplegable
= verdadero; [Sinopsis]es
texto
-edicion.longitud
= 1000;fin
fin
fin
Otro elemento que aparece en la definición que no hemos comentado son los atributos. Los atributos intervienen en todas las definiciones de ODL, y sirven para configurar el comportamiento de las definiciones. Los atributos que aquí se contemplan son relativos a campos y no nos detendremos en explicar su funcionamiento. En este mismo documento, abordaremos con mayor profundidad los atributos que afectan directamente a los contenedores.
Ahora, veamos cómo se refleja el código en la aplicación egExplorer de forma que nos permita crear objetos de tipo Libro:Una vez rellenado los campos, guardaremos el objeto. Pero, ¿cómo puedo obtener un listado de los libros que voy introduciendo? ¿Cómo puedo "ver mi estantería"?
¿Cómo implementamos una definición de sistema?
Nos disponemos a crear una instancia del sistema, un elemento estático en el que podremos visualizar los objetos que hemos creado. La forma de definir un objeto de sistema es similar a la definición de tipo pero sin incluir la palabra reservada tipo
. Es decir, [nombre]
es
contenedor
. Sin más preámbulos, veamos como se define nuestra "estantería":
[Estantería 1]es
contenedor
[Contenido]es
coleccion
-nombre_tabla
="TC$LIBROS"
;
contiene
[Libro]
columna
[Código] -columna_bd
.nombre
="CÓDIGO"
; -origen
= [Datos].[Código];
columna
[Título] -columna_bd
.nombre
="TÍTULO"
; -origen
= [Datos].[Título];
columna
[Autor] -columna_bd
.nombre
="AUTOR"
; -origen
= [Datos].[Autor];
columna
[Sinopsis] -columna_bd
.nombre
="SINOPSIS"
; -origen
= [Datos].[Contenido].[Sinopsis];fin
fin
Como ya hemos dicho, un contenedor puede almacenar componentes. En este caso, se utiliza la componente colección para visualizar los objetos creados. En la colección, especificamos los campos que queremos visualizar además de especificar el tipo de objetos.
A continuación veremos el contenido de nuestra estantería:
Al hacer clic en Estantería 1 accedemos a un objeto de sistema, que al tener contenida una colección, ésta se abrirá, y se visualizará el listado de los libros incluídos en nuestra estantería. Una vez en la colección, podremos crear aquellos contenedores que estén definidos en ella, que en este caso, sólo podrán ser de tipo Libro.
Propiedades de un contenedor
En ODL, cada contenedor que sea crea en el sistema adquiere una serie de propiedades. Éstas almacenan información relativa a cada contenedor creado, que puede resultar útil en tareas de mantenimiento del sistema de información:
- Nombre: es el nombre que adquiere el objeto. Si no se especifica, adquiere el nombre de la definición.
- ID: identificador del contenedor. Valor entero único generado para cada contenedor del sistema.
- Tipo: tipo del contenedor.
- Dominio: informa de la ubicación del recurso.
- Creado: fecha de creación del contenedor.
- Creador: usuario que ha creado el contenedor.
- Modificado: fecha de la última modificación del contenedor.
- Modificador: usuario que ha realizado la última modificación del contenedor.
- Protegido: evita que un objeto se pueda "mover", por ejemplo, a otras colecciones. Además, no permite la edición del objeto. Se puede asignar o desasignar.
Validaciones en un contenedor
ODL ofrece una operación llamada validación que permite definir condiciones en un contenedor. ¿Pero condiciones para qué?
Cuando creamos un objeto, es necesario garantizar la integridad de la información introducida. Pero además de introducir información, puede ser necesario introducirla con un formato determinado. Aquí es donde intervienen las validaciones. Se incluirán condiciones en el contenedor sobre ciertas entradas de información (campos), de manera que al querer guardar el objeto, no se llevará a cabo esta operación si no se cumplen las condiciones definidas.Antes de definir una condición debemos saber qué atributos tenemos que incluir. El atributo regla
indicará el campo sobre el que queremos que se evalúe la condición. El tipo
indicará el carácter de la condición, si es estricta será de tipo error, y si no, será de tipo advertencia. Finalmente indicaremos un mensaje de error en el atributo mensaje
, y una localización del campo afectado en forma de enlace en el atributo localizacion.componente
.
Utilizando el ejemplo anterior, definiremos condiciones en el contenedor Libro, y veremos su comportamiento a la hora de crear un objeto de tipo "Libro".
tipo
[Libro]es
contenedor
[Datos]es
formulario
[Código]es
timbre
-certificado
.valor
= [&Valor_secuencia]; -certificado
.secuencia
.nombre
="STR$LIBRO"
; -certificado
.secuencia
.longitud
= 4; [Título]es
texto
[Autor]es
texto
[Edición]es
texto
[Editorial]es
texto
[Contenido]es
seccion
[Tipo]es
texto
-edicion.valores
= $Matriz("Literario"
,"Biografía"
,"Científico"
,"Infantil"
); -apariencia.desplegable
= verdadero; [Sinopsis]es
texto
-edicion.longitud
= 1000;fin
fin
condicion
[Campo Título, está vacío] -regla
= [Datos].[Título] = vacio; -localizacion
.componente
= [Datos].[Título]; -tipo
= error; -mensaje
="Debe introducir el título del Libro"
;
condicion
[Año de la edición con 4 dígitos] -regla
= $longitudTexto([Datos].[Año de la edición]) < 4; -localizacion
.componente
= [Datos].[Año de la edición]; -tipo
= advertencia; -mensaje
="Formato del año incorrecto, debe tener 4 dígitos como mínimo.
En caso de ser un año inferior a 4 dígitos, añadir ceros a la izquierda"
;
condicion
[Tipo de libro no aceptado] -regla
= ([Datos].[Contenido].[Tipo] <>"Literario"
)y
([Datos].[Contenido].[Tipo] <>"Biografía"
)y
([Datos].[Contenido].[Tipo] <>"Científico"
)y
([Datos].[Contenido].[Tipo] <>"Infantil"
); -localizacion
.componente
= [Datos].[Contenido].[Tipo]; -tipo
= error; -mensaje
="Por favor, seleccione uno de los valores del desplegable. Este campo no puede tener otro valor"
;fin
Ciclo de eventos de un contenedor
Aprovechando que en el apartado anterior hemos intentado crear un objeto definiendo condiciones en la definición de tipo, es un buen momento para entender los eventos que se producen al crear un objeto.
El primer evento que se produce es la verificación de validaciones, es decir, que antes de que se guarde el objeto, la integridad de la información introducida tiene que ser la exigida en su definición. Si esto se cumple, el siguiente evento es guardar el objeto. Una vez almacenado, el tercer evento es actualizar las tablas de colección, de forma que el objeto creado aparezca en aquellas colecciones donde esté incluído el tipo del objeto. Y finalmente, se ejecutan las exportaciones asociadas a ese contenedor.Herencia en contenedores
ODL permite la herencia entre contenedores. Esto quiere decir que es posible realizar una definición de tipo a partir de otra definición "padre". Las definiciones de tipo derivadas heredarán todos los componentes definidos en la definición "padre".
Existe también la opción de redefinir componentes o campos en un contenedor derivado, así como definir nuevos componentes. Además, ODL permite declarar tipos abstractos, de forma que no se podrán crear objetos de ese tipo.
Veamos a continuación un ejemplo de herencia en contenedores, utilizando el contenedor tipo Libro como contenedor padre:
tipo
abstracto
[Libro]es
contenedor
[Datos]es
formulario
[Código]es
timbre
-certificado
.valor
= [&Valor_secuencia]; -certificado
.secuencia
.nombre
="STR$LIBRO"
; -certificado
.secuencia
.longitud
= 4; [Título]es
texto
[Autor]es
texto
[Edición]es
texto
[Editorial]es
texto
[Contenido]es
seccion
[Tipo]es
texto
-edicion.valores
= $Matriz("Literario"
,"Biografía"
,"Científico"
,"Infantil"
); -apariencia.desplegable
= verdadero; [Sinopsis]es
texto
-edicion.longitud
= 1000;fin
fin
fin
En este caso, hemos declarado el tipo Libro como abstracto, de forma que no podremos crear un objeto de tipo Libro. Hemos definido un contenedor "Literario" a partir de Libro, donde redefinimos el campo [Tipo] que hay en el tipo padre, y además hemos añadido una tabla al formulario.tipo
[Literario]es
[Libro] [Datos]es
formulario
[Contenido]es
seccion
[Tipo]es
texto
-edicion.modo
= referencia; -edicion.valor
="Literario"
;fin
[Artículos relacionados]es
tabla
[Título del artículo]es
texto
; [Autor del artículo]es
texto
; [Año del artículo]es
texto
;fin
fin
fin
A la hora de redefinir un campo, hay que tener en cuenta los componentes en las que está definido, para incluírlas también en la definición. El campo [Tipo] que hemos redefinido está incluído en una sección que a su vez está incluído en un formulario. Por tanto, hemos incluído el formulario y la sección en el nuevo contenedor "Literario" para referenciar el campo [Tipo] y poder redefinirlo.
El resultado de nuestro contenedor "Literario" será el formulario definido en el tipo Libro con el campo [Tipo] redefinido y el añadido de un campo tabla.
En caso de querer incluir algún atributo o redefinirlo, se realizará adoptando el mismo comportamiento que para redefinir un campo, incluyendo aquellas definiciones necesarias para referenciar al atributo en cuestión, como hemos podido ver en el ejemplo.Atributos
A la hora de definir un contenedor, es probable que queramos configurar ciertos aspectos en su definición de forma que satisfagan las necesidades del sistema de información. Para esto, existen los atributos.
En ODL existen atributos generales sobre los recursos (contenedores, tareas, habitaciones, enumerados y roles) y otros atributos exclusivos de los contenedores. Entre ellos, se distinguen dos tipos de atributos: accesibles y ocultos (el programador no puede asignarle un valor, esa tarea la realiza la plataforma). A continuación listaremos la especificación de aquellos atributos que afectan exclusivamente a los contenedores, para finalmente realizar un ejemplo con aquellos atributos que pueden ser asignables por el programador.Atributos de los recursos
Atributo | Tipo | Valor por defecto | Observaciones |
---|---|---|---|
ayuda
|
Texto | Marcador dentro de la ayuda | |
descripcion
|
Texto | [Nombre] | Comentario sobre el recurso |
etiqueta
|
Texto | [Nombre] | Etiqueta del recurso. Expresión que aparecerá del contenedor cuando sea vinculado. |
grupo
|
Texto | Grupo de recursos en el que se clasifica | |
icono
|
Texto | Identificar del icono | |
plantilla_impresion
|
Texto | Nombre del fichero de la plantilla de impresión (.ar) | |
publico
|
Lógico | Verdadero | Indica que al recurso pueden acceder todos los usuarios |
registrar_accesos
|
Texto | Nada | Registran los accesos al recurso (.log). Nunca (Nada), cuando se accede (Lectura) o cuando se modifique (Escritura) |
mostrar_propiedades
|
Lógico | Verdadero | Se desea mostrar la pestaña de propiedades del recursos |
Atributo oculto | Tipo | Observaciones |
---|---|---|
asistente
|
Definicion asistente | Asistente asociado al recurso |
habitaciones
|
{Definicion recurso} | Habitaciones a las que se puede enviar el recurso |
impresiones
|
Definicion impresion | Formatos de impresión que se pueden realizar del contenedor |
verificación
|
Definicion verificacion | Verificación a realizar sobre el recurso |
Atributos de los contenedores
Atributo | Tipo | Valor por defecto | Observaciones |
---|---|---|---|
nombre
|
Expresión / Texto | [Nombre de la definición] | Fórmula para sugerir un nombre para el contenedor |
referencia
|
Expresión / Texto | Fórmula para calcular la referencia de un contenedor | |
asunto
|
Texto |
Atributo oculto | Tipo | Observaciones |
---|---|---|
colecciones
|
{Definición colección} | Colecciones en las que se puede almacenar el contenedor |
exportaciones
|
{Definición exportación} | Exportaciones que tiene definidas el contenedor |
asistentes
|
{Definición asistente} | Asistentes que tiene definidos el contenedor |
asistente_automatico
|
{Definición asistente} | Asistente que se ejecuta automáticamente al crear el contenedor |
tareas
|
{Definición tarea} | Tipos de tareas que se pueden lanzar sobre el contenedor |
referencias.definicion
|
{Definición} | Referencias que se realizan de manera indirecta al contenedor, tanto colecciones como exportaciones. |
referencias.columna
|
Texto | Nombre de la columna donde se almacena la referencia indirecta |
Ejemplo: uso de atributos
Atributo nombre
tipo
[Libro]es
contenedor
-nombre
="'Libro de la biblioteca'"
; [Datos]es
formulario
... ... ...fin
fin
En caso de no asignar ningún valor, el objeto obtendrá el nombre del tipo, en este caso, Libro. Pero además, este atributo permite definir una expresión, utilizando funciones de librería y operadores, de forma que pueda obtener diferentes valores.
tipo
[Libro]es
contenedor
-nombre
="$si([Datos].[Autor]
=vacio
,[Datos].[Título],[Datos].[Autor] + "" - "" + [Datos].[Título]"
; [Datos]es
formulario
... ... ...fin
fin
El resultado de la expresión sería el siguiente:
Atributo mostrar_propiedades
tipo
[Libro]es
contenedor
-nombre
="$si([Datos].[Autor]
=vacio
,[Datos].[Título],[Datos].[Autor] + "" - "" + [Datos].[Título]"
; -mostrar_propiedades
= falso; [Datos]es
formulario
... ... ...fin
fin
Si no se especifica, su valor será verdadero. Al ponerlo a falso, la pestaña propiedades de cada objeto "Libro", no se mostrará al usuario:
Atributo icono
[Estantería 1]es
contenedor
-icono
="Estante"
; [Contenido]es
coleccion
... ... ...fin
fin
Como ya habíamos dicho, hay atributos para variar el aspecto visual en el entorno egExplorer. Este atributo es uno de ellos. Podemos especificar un icono, en este caso para nuestro objeto de sistema Estantería_1:
Atributo descripcion
[Estantería 1]es
contenedor
-icono
="Estante"
; -descripcion
="Estantería de libros de la biblioteca"
; [Contenido]es
coleccion
... ... ...fin
fin
Este atributo muestra la descripción del contenedor. En este caso, vemos como aparece la descripción al abrir nuestro objeto de sistema Estantería_1. Si nos fijamos en la imagen anterior, vemos que en vez de la descripción, aparece el nombre de la colección [Contenido]:
Atributo publico
Este atributo por defecto tiene asignado como valor verdadero, por eso no hemos tenido ningún problema para acceder a ninguno de los objetos que hemos creado. Si lo incluimos en Estantería 1, al querer abrir el objeto de sistema nos saldrá un mensaje de error. Si por el contrario lo incluimos en la definición de tipo Libro, podremos abrir el objeto de sistema Estantería 1, nos aparecerá la lista de libros pero no podremos abrir ningún objeto de tipo Libro. En este caso, lo definimos en el objeto de sistema. Prueba a hacerlo también con el contenedor de tipo "Libro":
[Estantería 1]es
contenedor
-icono
="Estante"
; -descripcion
="Estantería de libros de la biblioteca"
; -publico
= falso; [Contenido]es
coleccion
... ... ...fin
fin
En caso de tener asignado un rol que nos permita abrir o crear un contenedor al que le hemos incluido el atributo publico
con valor falso, prevalecerán los permisos que tenga ese usuario sobre el atributo publico
en caso de contradicción.
Atributo grupo
Cuando accedemos a una colección y picamos en Nuevo contenedor, nos aparece una ventana con las definiciones de contenedores que están incluídas en la colección y sobre las cuáles podremos crear objetos. Es posible que al ser muchas definiciones nos interese agruparlas por alguna característica concreta. Para ello, utilizaremos el atributo grupo
.
Imaginemos que tenemos una colección que contiene todos aquellos documentos de entrada y salida que se generan en nuestra organización, y que hay varias definiciones de documentos de entrada y varias de documentos de salida. Queremos crear dos grupos, uno llamado Documentos de entrada y otro Documentos de salida. Como hay varias definiciones que nosotros consideramos como documentos de entrada, debemos añadir el atributo grupo
seguido de su valor:
tipo
[Documento de entrada 1]es
contenedor
... ... -grupo
="Documentos de entrada"
; ...fin
Esto lo haremos con todas las definiciones que queramos agrupar en Documentos de entrada. Lo mismo haremos con las definiciones que queramos incluir en el grupo Documentos de salida:
tipo
[Documento de salida 1]es
contenedor
... ... -grupo
="Documentos de salida"
; ...fin
Ahora, si accedemos al egExplorer y entramos a la colección donde están incluídas las definiciones agrupadas, veremos lo siguiente: