## Como programar Informes

Esta página muestra los puntos de interés para la gente que quiera escribir informes a medida para GenJ

1. Aspectos básicos
2. Propiedades e Internacionalización
3. Opciones
4. Cargando mas Código Java
5. Obtener Datos (Parte 1): Usando métodos sobre objetos
6. Obtener Datos (Parte 2): Usando etiquetas y propiedades

## Aspectos básicos

Un informe GenJ es una clase Java que extiende el tipo abstracto genj.report.Report. Al escribir sus propias funcionalidades debe empezar por definir su propia clase en un fichero fuente y colocarlo en el subdirectorio de informes. Su nombre debe empezar por Report (Report*).

Asumiremos que quiere escribir el informe Test. Crearemos un fichero de texto llamado ReportTest.java en ./reports. Despues compílelo con el script en el mismo directorio. Este script ejecuta javac - el compilador java. El resultado final es un fichero llamado ReportTest.class que GenJ puede cargar y ejecutar despues de ser seleccionado en la Vista de Informes.

Veamos el fichero fuente ReportTest.java. Contiene una definición de clase pública que extiende Report). Parte del proceso es que debe implementar public void start(Object context) - el punto de entrada en Report. Podemos usar todos los métodos proporcionados por el supertipo Report - aquí sólo usaremos el método println() que vuelca texto en un cuadro de texto que el usuario ve al ejecutar el informe.

      import genj.gedcom.*;
      import genj.report.*;

      import genj.report.Report;

      public class ReportTest extends Report {

        /**
         * el  metodo principal
         */
        public void start(Object context) {
          println("Hello World!");
        }

      }

Ahora queremos que el informe se integre adecuadamente en la Vista de Informes con nombre, algo de información básica y una referencia al autor. Para llevar a cabo esto crearemos un fichero llamado ReportTest.properties en el mismo directorio que el informe y le pondremos la información adecuada:

      # Fichero: ReportTest.properties
      # estos son los recursos de texto de ReportTest
      name   = Un simple Test
      info   = Informe de prueba para GenJ
      author = quien hizo esto?

El informe debería funcionar bien pero ahora hemos de hacer que haga algo útil para los usuarios. Por defecto los informes pueden ejecutarse sólo en un contexto Gedcom - esto significa que el argumento de start() será una instancia Java del tipo Gedcom. Así que asumiremos context instanceof Gedcom. Un caso simple de uso podría ser el número de individuos en el objeto Gedcom que le hemos pasado. El método start() será ahora:

        public void start(Object context) {
          // el contexto es una instancia de Gedcom por defecto
          Gedcom gedcom = (Gedcom)context;
          // calculamos el número de individuos
          int count = gedcom.getEntities(Gedcom.INDI).size()
          // y lo mostramos
          println("Gedcom "+gedcom.getName()+" contains "+count+" individuals");
        }

La API ( Interfaz Pública da la Aplicación ) de genj.report.Report y de genj.gedcom.Gedcom contienen muchos métodos para acceder y presentar la información contenida ( vease los javadocs de GenJ para mas información )

## Propiedades e Internacionalización

Para dar soporte a la internacionalizaci?n el informe NO debería imprimir cadenas de texto directamente. En lugar de ello debería usar ficheros de propiedades para definir las cadenas a imprimir y entonces extraerlas del fichero. De esta forma el fichero de propiedades puede ser facilmente traducido. Por ejemplo NO haga esto: `println("Birth Date is");` En su lugar haga esto:

        println(i18n("BirthDateIs"));

y ponga una linea como ésta en su fichero de propiedades:

        BirthDateIs = Birth Date is

## Opciones

Todos los informes tienen un panel de opciones, que puede usarse facilmente, al crear variables de clase públicas en la clase informe y en el fichero de propiedades. Por ejemplo si su informe genera texto por defecto y ademas puede crear HTML, y quiere dar al usuario la oportunidad de elegir lo que quiere. Para ello cree una variable pública en su clase informe:

        public boolean generateHTML = true ;

y añada texto al fichero de propiedades:

        generateHTML = ¿Quiere la salida en código HTML?

cargue su informe y mire en el panel de propiedades los resultados.

Para crear un menú desplegable use estas variables públicas

        public int outputFormat = 0;
        public static String[] outputFormats = { "Soundex", "Metaphone", "Double Metaphone", "NYSIIS", "Phonex" };

y este fichero de propiedades:

        outputFormat=Output format
        outputFormat.es=Formato de salida

Hay mas opciones complejas. Mire en ReportEvent.java para mas ejemplos.

## Cargando mas Código Java

Todo el código del directorio report se compila con el script rcompile, y todo está cargado en GenJ, Así si quiere usar otras clases en su informe copie los ficheros .java o .class en ese directorio y serán cargados en espera de ser usados

Por ejemplo, si quiere usar DMSoundex class, ponga DMSoundex.java en el directorio report y ejecute rcompile. Ahora esta asequible pero no aparece como informe porque no es subclase de genj.report.Report.

## Obtener datos (Part 1): usando metodos sobre objetos

Los objetos java que almacenan información del fichero GEDCOM tienen métodos para acceder a nombre, fechas, hijos y padre (pero no tantos como esperaría ). Algunos ejemplos:

        //Methodos de la clase Indi (Individuals)
        //No es a lista completa !
        String getBirthAsString()   // Nota: es una fecha (no un objecto)
        String getDeathAsString()   // Nota: es una fecha (no un objecto)
        String getName()
        String getFirstName()
        String getLastName()
        Fam getFamc()               // da la familia donde esta persona es hijo
        Indi getFather()
        Indi getMother
        Indi[] getChildren()
        //Metodos de la  clase Fam (Families)
        //No es una lista completa !.
        Indi getChild(int which)
        Indi[] getChildren()
        Indi getHusband()
        Indi getWife()

Tambien puede mirar la clase PropertyDate y los metodos que devuelven estos objetos desde otras clases

## Obtener Datos (Part 2): Usando etiquetas y propiedades

La mayor parte de los datos de un fichero GEDCOM es asequible por las etiquetas, mas que por métodos u objetos.Por ejemplo para obtener información de naturalización sobre una persona no debería hacer esto: `indi.getNaturalization()`. En su lugar deber?a hacer esto:

     PropertyEvent naturalization = (PropertyEvent)indi.getProperty(new TagPath("INDI:NATU")) ;

O puede obtener información mas especifica así:

     PropertyDate prop = (PropertyDate)indi.getProperty(new TagPath("INDI:NATU:DATE"));
     String dateOfNaturalization = prop.getValue() ;

Obtener notas es un poco mas complejo. Este codigo devolverá un evento nota como una cadena si el evento tiene una nota:

       // Ejemplo
       PropertyEvent immigration = (PropertyEvent)indi.getProperty(new TagPath("INDI:IMMI")) ;
       String note = getNote(immigration) ;
       if (note==null) note = i18n("noNote") ;
       println(note) ;

       //

       private String getNote(PropertyEvent e) {
           if (e==null) return null ;
           MultiLineProperty prop = checkNote(e.getProperty("NOTE")) ;
           if (prop==null) return null ;
           return prop.getLinesValue()  ;
       }

      /**
       * Comprueba si hay NOTE y si la hay
       * devuelve una  MultiLineProperty para acceder a ella
       */
      MultiLineProperty checkNote(Property prop) {
           if (prop==null) return null ;

        // ha de ser 'NOTE'
       if (!prop.getTag().equals("NOTE"))
         return null;

        // ver si prop es una referencia a  Note
        if (prop instanceof PropertyNote) {
          // .. jump to the referenced target
          prop = ((PropertyNote)prop).getTarget();
        }

        // ver si tenemos una propiedad multilinea
        // con una nota
        if (prop instanceof MultiLineProperty )
          return (MultiLineProperty)prop;

        // no candidato
        return null;
      }

En orden a usar estas cadenas de etiquetas necesita saber los códigos de cuatro letras que son parte del estandar GEDCOM. He aquí un par de enlaces con información en inglés:
http://www.math.clemson.edu/~rsimms/genealogy/ll/gedcom55.pdf
http://www.gendex.com/gedcom55/55gcappa.htm

Tenga en cuenta este resumen con las mas comunes:
De primer nivel: INDI (individuo), FAM (Familia)
Eventos: BIRT (Nacimiento), DEAT (Fallecimiento), IMMI (Inmigracion),NATU (Naturalizacion), BAPT (Bautismo)
Otros: CHIL (Hijo), FAMC (Familia donde se es hijo), HUSB (Esposo), WIFE (Esposa)
Componentes: ADDR (direcci?n), DATE (fecha), NOTE (Nota), PLAC (lugar)

La vista de edición muestra exactamente que etiquetas tiene datos para que entidades y es una buen manera de comprender los datos y estructuras de GEDCOM

Mire en el código fuente del informe Events para ver como son usadas las etiquetas. También puede mirar el fichero GEDCOM para ver como se disponen las etiquetas y subetiquetas.