Doc Guia Usuario API v2 0

21
Aplicación de Factura Electrónica: Guía de Usuario para el API de Facturae 2.0

Transcript of Doc Guia Usuario API v2 0

Aplicación de Factura Electrónica:

Guía de Usuario para el API de Facturae 2.0

2

Control de Cambios

VERSIÓN FECHA AUTOR DESCRIPCIÓN

1.0 11/07/2008 Fernando Manzano – Pablo Lorente Versión inicial

1.1 28/07/2008 Pablo Lorente Nueva funcionalidad: extensión del

recubrimiento de los componentes de firma añadiendo la validación de firma

1.2 01/08/2008 Fernando Manzano Se incluye información acerca del uso y configuración de las “Extensions”

2.0 04/06/2010 Fernando Manzano

Nueva versión en la que se incluye: Soporte para la versión 3.2 de Facturae,

nueva estructura del API y nuevos métodos de firma.

3

Índice

Control de Cambios ______________________________________________________ 2

Índice _________________________________________________________________ 3

Introducción____________________________________________________________ 4 Objetivo y alcance ___________________________________________________________ 4 Audiencia __________________________________________________________________ 4 Descripción general __________________________________________________________ 4

Instalación _____________________________________________________________ 5 Contenido __________________________________________________________________ 5 Instalación__________________________________________________________________ 5

Componentes ___________________________________________________________ 6 Arquitectura________________________________________________________________ 6 Componentes de la API _______________________________________________________ 7

MarshallerUtil ____________________________________________________________________ 7 UnmarshallerUtil __________________________________________________________________ 9 ValidatorUtil ____________________________________________________________________ 10 Validadores contables _____________________________________________________________ 11 SignatureUtil ____________________________________________________________________ 11

Componentes de soporte _____________________________________________________ 12 GenericFacturae__________________________________________________________________ 12 Otros componentes _______________________________________________________________ 13

Configuración _________________________________________________________ 15 Configuración del componente de firma ________________________________________ 15 Configuración de las propiedades del API ______________________________________ 15 Configuración de la imagen de cabecera de la ventana de selección de certificado______ 16 Configuración del sistema de logs _____________________________________________ 17 Configuración del lenguaje ___________________________________________________ 17 Advertencias_______________________________________________________________ 18

ANEXO A: USO DE EXTENSIONS _______________________________________ 19 Introducción _______________________________________________________________ 19 Configuración______________________________________________________________ 19 Creación del elemento “Extensions” ___________________________________________ 20

4

Introducción

Objetivo y alcance El Ministerio de Industria, Turismo y Comercio (MITyC), como parte del Plan Avanza, pretende

impulsar la facturación electrónica entre pequeñas empresas (PYMES y microPYMES) y trabajadores autónomos. Para conseguir su objetivo, ha desarrollado herramientas capaces de gestionar, de forma sencilla e intuitiva, facturas electrónicas que cumplan el formato de facturación electrónica desarrollado por la propia Administración en colaboración con otras entidades.

Así mismo, como complemento a este objetivo principal, el MITyC se ha propuesto facilitar a

las empresas de mayor envergadura (tanto por número de empleados como por volumen de negocio) la integración de la factura electrónica en sus ERPs (Enterprise Resource Planning1) particulares. Para tal cometido, se facilita un API (Application Programming Interface2) que contenga la funcionalidad necesaria para gestionar facturas con formato Facturae, dejando en manos de dichas empresas la labor de integración final en sus aplicaciones propietarias.

El presente documento tiene como finalidad detallar las diversas funcionalidades ofrecidas por

el API. Para ello se contemplará un abanico de procesos y operaciones lo más amplio posible a fin de conseguir proporcionar una API fiable y completa, que se ajuste verdaderamente a las necesidades de las empresas.

Audiencia

Esta guía está dirigida al grupo de desarrollo de la aplicación propietaria que desee hacer uso del formato Facturae.

Descripción general

Desarrollo de un API Java con la funcionalidad necesaria para manejar facturas que cumplan con el formato Facturae (en la fecha de redacción de este documento, versiones 3.0, 3.1 y 3.2). El objetivo es facilitar a las empresas, que así lo deseen, la integración de un paquete de funcionalidad Facturae en sus respectivas aplicaciones.

1 Los sistemas de planificación de recursos empresariales (ERP) son sistemas de información gerenciales que integran y manejan muchos de los negocios asociados con las operaciones de producción y de los aspectos de distribución de una compañía comprometida en la producción de bienes o servicios. 2 Una API representa una interfaz de comunicación entre componentes software. Se trata del conjunto de llamadas a ciertas bibliotecas que ofrecen acceso a ciertos servicios desde los procesos y representa un método para conseguir abstracción en la programación, generalmente (aunque no necesariamente) entre los niveles o capas inferiores y los superiores del software. Uno de los principales propósitos de una API consiste en proporcionar un conjunto de funciones de uso general.

5

Instalación

Contenido

El API está constituido por un único fichero comprimido que incluye las librerías y la documentación al respecto. En más detalle, el contenido del fichero comprimido que constituye el API completo es el siguiente:

• Facurae-API-2.0.jar • Lib Librerías de soporte (ya especificadas en este documento)

• META-INF Información adicional del API

o disclaimer.txt y exencion_responsabilidades.txt

o /licencias/ ficheros de licencia en distintos idiomas (castellano, inglés,

euskera, catalán y gallego)

o README.txt y LEEME.txt

• Guía de usuario (este documento) • Javadoc (en formato JAR)

Instalación Extraer las librerías JAR contenidas en el directorio <lib>, junto con el JAR del API llamado

Facturae-API-2.0.jar y situado en el raíz. Después añadirlas al classpath de la aplicación con la que se quiera integrar.

6

Componentes

Arquitectura

Este API se divide en dos partes bien diferenciadas:

• Por un lado están los componentes de marshal, unmarshal y validación. Ayudan a la gestión de datos XML, permitiendo la conversión recíproca de datos XML y objetos Java.

• Por otro lado se encuentra el componente de firma, encargado de realizar la firma

digital de una factura electrónica. El API está compuesto por las siguientes librerías (cada grupo de librerías corresponde,

respectivamente, a las partes diferenciadas comentadas anteriormente):

• Facturae-API-2.0.jar Es el núcleo del API y contiene los componentes básicos. • Librerías JAXB Contiene la lógica necesaria para realizar la transformación entre

datos XML y objetos Java. Permite realizar los procesos de marshal (java xml) y unmarshal (xml java)

o jaxb-api-2.1.jar o stax-api-1.0-2.jar o jaxb-impl-2.1.12.jar o activation-1.1.jar o jsr173_1.0_api.jar

• swing-layout-1.0.3.jar Contiene extensiones de los “layout” de swing. Son empleados por la interfaz de usuario de selección de certificado.

• Componentes de logs Se utiliza la librería commons-logging.jar para flexibilizar el

sistema de logs empleado por el desarrollador. Se incluye log4j por defecto.

o commons-logging.jar o log4j-1.2.14.jar

• FacturaEBridge.jar “Bridge” de firma. Contiene la interfaz “fachada” de los servicios de firma.

• Componentes de firma Componentes de firma empleados por el API. Se conecta al

“bridge” anterior mediante configuración. El desarrollador puede conectar otro componente de firma si así lo deseara.

7

Facturae API Bridge

Componentes defirma

sign.properties: Contiene una propiedadque conecta el "bridge" con el componentede firma.- jaxb-api-2.1.jar

- stax-api-1.0-2.jar- jaxb-impl-2.1.12.jar- activation-1.1.jar- jsr173_1.0_api.jar- swing-layout-1.0.3.jar- commons-loggin-1.1.jar- log4j-1.2.14.jar - MITyCLibAPI-1.0.5.jar

- MITyCLibCert-1.0.4-mscapi5.jar- MITyCLibCert-1.0.5.jar- MITyCLibOCSP-1.0.5.jar- MITyCLibPolicy-1.0.5.jar- MITyCLibTrustInternal-1.1.0.jar- MITyCLibTSA-1.0.5.jar- MITyCLibXADES-1.0.5.jar- bcprov-jdk15-1.43.jar- bctsp-jdk15-1.43.jar- commons-logging-1.1.jar- commons-codec-1.3.jar- commons-httpclient-3.0.1.jar- commons-lang-2.4.jar- log4j-1.2.14.jar- jss-4.2.5.jar- bcmail-jdk15-1.43.jar (*)- serializer-2.7.1.jar (*)- xml-apis-1.3.04.jar (*)- xalan-2.7.1.jar (*)- xmlsec-1.4.2-ADSI-1.0.jar

(*) No necesarias para la compilación.

- FEBComp10-1.0.4.jar

Ilustración 1 Arquitectura general del API

Componentes de la API Los componentes de funcionalidad básica del API se localizan en el paquete

“es.mityc.facturae.utils”.

MarshallerUtil

Descripción Tiene por cometido la serialización de un objeto Java “Facturae” en un fichero de datos XML

que representa una factura con formato Facturae.

8

Funciones Consta de varios métodos “marshal”, además del método encargado de devolver una instancia

de la clase (que a su vez utiliza otros métodos de creación de instancias y constructores privados). Cada uno de los métodos “marshal” tiene un formato distinto de salida: fichero, nodo…

Caso de uso 1) Crear un objeto Java “Facturae” de la versión 3.0, 3.1 ó 3.2:

Para ello, incluidos en el API, se ofrecen todos los objetos necesarios para representar una factura electrónica en clases Java, bajo los paquetes es.mityc.facturae30, es.mityc.facturae31 y es.mityc.facturae32 respectivamente. El objeto raíz se denomina “Facturae”. Para este ejemplo, se utilizará una factura 3.2. El proceso de “marshal” para una factura 3.0 y 3.1 es idéntico teniendo en cuenta las particularidades de la versión del formato a la hora de construir el objeto “Facturae” en cuestión. Código // Construir el objeto facturae32Object. es.mityc.facturae32.Facturae facturae32Object = new es.mityc.facturae32.Facturae(); // Utilizar los métodos “set” de Facturae, para establecer el contenido de la factura. es.mityc.facturae32.FileHeaderType cabecera32Object = new es.mityc.facturae32.FileHeaderType(); String schemaVersion = "3.2"; cabecera32Object.setSchemaVersion(schemaVersion); … invoice32.setFileHeader(cabecera32Object); …

2) Crear una instancia de “MarshallerUtil”: Código // Obtener un “MarshallerUtil” para la versión 3.2 de Facturae. MarshallerUtil marshallerUtil32 = MarshallerUtil.getInstance(FacturaeVersion.FACTURAE_32); // El objeto creado cargará el contexto y extensión adecuados.

3) Realizar el “marshal”:

Código // Utilizar el objeto creado “MarshallerUtil”, invocando el método marshal. marshallerUtil32.marshal(facturae32Object, "nombreFicheroFactura"); File ficheroFactura = new File("nombreFicheroFactura.xsig"); // Durante el proceso podría lanzarse una “MarshalExceptioin”.

9

UnmarshallerUtil

Descripción Su finalidad es dirigir la deserialización de un XML que represente una factura con formato

Facturae en un objeto Java “Facturae”.

Funciones Consta de varios métodos “unmarshal”, además del método encargado de devolver una

instancia de la clase (que a su vez utiliza otros métodos de creación de instancias y constructores privados). Cada uno de los métodos “unmarshal” tiene un formato distinto de salida: fichero, nodo…

Caso de uso 1) Partimos de un fichero XML o XSIG en función de si el fichero representa una factura 3.0,

3.1 ó 3.2 respectivamente: Para este ejemplo, se utilizará una factura 3.2. El proceso de “unmarshal” para una factura 3.0 y 3.1 es idéntico teniendo en cuenta la versión del objeto Java “Facturae” que se produce en cada caso. Código // Construir el objeto facturae32Object que recibirá el resultado del unmarshal. java.io.File factura32 = new java.io.File( “factura32.xsig” ));

2) Crear una instancia de “UnmarshallerUtil”:

Código // Obtener un “UnmarshallerUtil” para la versión 3.2 de Facturae. UnmarshallerUtil unmarshallerUtil32=UnmarshallerUtil.getInstance(FacturaeVersion.FACTURAE_32); // El objeto creado cargará el contexto adecuado.

3) Utilizar el componente “UnmarshallerUtil”:

Código // Utilizar el objeto creado “UnmarshallerUtil”, invocando el método unmarshal. Se obtiene un objeto Facturae de la versión 3.2 es.mityc.facturae32.Facturae invoice32 = (es.mityc.facturae32.Facturae)unmarshallerUtil32.unmarshal(factura32); // Durante el proceso podría lanzarse una “UnmarshalExceptioin”.

10

ValidatorUtil

Descripción Su propósito es verificar la validez de un fichero XML o XSIG (en función de si la versión del

formato Facturae es 3.0, 3.1 ó 3.2) que representa una factura con formato Facturae.

Funciones Implementa un método denominado “validate” que recibe como parámetros el fichero XML o

XSIG que representa una factura con formato Facturae y una cadena con la versión del formato Facturae correspondiente a dicho fichero. Devuelve “verdadero” o “falso” en función de si pasa la validación o no. El método está sobrecargado para aceptar, también, un objeto de tipo “source”.

Un fichero XML/XSIG será declarado válido si presenta una estructura adecuada de acuerdo al

esquema XSD asociado (esquema de Facturae 3.0, esquema de Facturae 3.1 ó esquema de Facturae 3.2, junto con el esquema de firma digital).

Caso de uso 1) Partimos de un fichero XML o XSIG en función de si el fichero representa una factura 3.0 ó

3.1 / 3.2 respectivamente:

Para este ejemplo, se utilizará una factura 3.2. El proceso de “validate” para una factura 3.0 ó 3.1 es idéntico teniendo en cuenta el segundo parámetro de la función, que indica la versión que se está validando. Código // Construir el fichero factura32. java.io.File factura32 = new java.io.File( “factura32.xsig” ));

2) Utilizar el componente “ValidatorUtil”: Código // Crear un objeto de tipo ValidatorUtil.

ValidatorUtil vu = new ValidatorUtil();

// Invocar el método validate. Parámetros: el fichero a validar y la versión correspondiente.

vu.validate(factura32, "3.2");

// Durante el proceso podría lanzarse una “ValidationExceptioin”.

11

Validadores contables En esta versión del API no existen validadores contables. Puede utilizar los validadores

contables aportados por la AEAT desde su página Web: www.aeat.es

SignatureUtil

Descripción Este componente permite firmar digitalmente la factura electrónica empleando un certificado de

usuario.

Funciones Esta clase implementa un método estático “sign” sobrecargado de diversas formas. También

implementa varias versiones de un método “validateSignature”. En esta versión del API se permite la especificación de un almacén de certificados. En el caso

de no especificarlos se utilizan los que existan por defecto en un fichero de propiedades. Se han mantenido los métodos antiguos, sin indicar almacén, para mantener la compatibilidad.

También se incluye la posibilidad de paso por parámetro del certificado a utilizar como

alternativa a la interfaz gráfica de selección de certificados. Además de lo indicado se permite el uso de distintos formatos de entrada: Documento,

Fichero… para las distintas modalidades del método de firma.

Caso de uso 1) Partir de un fichero XML / XSIG, dependiendo de si se trata de un borrador (de cualquier

versión) o de una factura con formato 3.1 ó 3.2 firmada, respectivamente:

Para este ejemplo, se utilizará una factura 3.2. Código // Construir el fichero factura32. java.io.File factura32 = new java.io.File( “factura32.xsig” ));

2) Invocar al método “sign”, pasando como parámetros la factura (o borrador) a firmar y la

ruta donde se quiera ubicar la factura firmada: Código // Invocar al método estático “sign”.

Document docSigned = es.mityc.facturae.utils.SignatureUtil.sign(factura32,”almacen” ,”parametro”); * * Ejemplo: almacén = “Explorer”, parámetro = “”.

12

En cuanto a la validación de la firma:

Caso de uso 1) Partir de un fichero XML / XSIG, dependiendo de si se trata de un borrador (de cualquiera

de las dos versiones) o de una factura con formato 3.1 ó 3.2 firmada, respectivamente:

Para este ejemplo, se utilizará una factura 3.2. Código // Construir el fichero factura32. java.io.File factura32 = new java.io.File( “factura32.xsig” ));

2) Invocar al método “validateSignature”, pasando como parámetros la factura (o borrador) a

firmar y la ruta donde se quiera ubicar la factura firmada:

Código // Invocar al método estático “sign”.

java.util.Map<String, Object> b = es.mityc.facturae.utils.SignatureUtil.validateSignature(factura32); // Si la validación ha sido correcta se devuelven características de la firma: / ******************************************************************************************************* * certificado (X509Certificate): certificado con el que se ha firmado. * sign.date (Date): fecha de la firma (no es sello de tiempo). * sign.roles (List<String>): roles aplicados a la firma. * sign.xades.schema (String): esquema XAdES de la firma. Valores posibles: 1.2.2 y 1.3.2. * sign.policy (String): política asociada a la firma. Valores posibles: facturae30 y facturae31. ******************************************************************************************************* / // En caso contrario, se lanza una excepción “InvalidSignatureException”.

Componentes de soporte

Los componentes de soporte son utilizados por los componentes básicos, siendo transparentes para el usuario final del API.

GenericFacturae

Descripción Se ha creado una clase genérica para agrupar a todas las facturas Facturae

independientemente de la versión a la que pertenecen. Las clases “Facturae” de las distintas versiones heredan de esta clase genérica “GenericFacturae”.

13

Otros componentes Estos componentes se agrupan en los siguientes paquetes:

• Paquete es.mityc.facturae.utils.adapters

Algunas clases JAVA no se mapean de forma natural a una respresentación XML (por

ejemplo HashMap). Se requieren clases adaptadoras para establecer como deben realizar los procesos de marshal y unmarshal. Estas clases heredan de la clase abstracta “XmlAdapter”.

Esta clase abstracta define métodos para adaptar un tipo dado a un tipo determinado o

viceversa. Los métodos se corresponden con los procesos de marshal y unmarshal.

• Paquete es.mityc.facturae.utils.mappers

Se crea una clase personalizada que hereda de “NamespacePrefixMapper” para

determinar el prefijo a utilizar en función de la URI que identifica un determinado espacio de nombres (‘namespace’).

• Paquete es.mityc.facturae.utils.auth

Contiene una clase personalizada que hereda de java.net.Authenticator. Simplemente almacena el nombre de usuario y contraseña para autenticarse en el proxy durante las validaciones de certificado OCSP (si existiera proxy).

• Paquete es.mityc.facturae.utils.constants

Constantes del API.

• Paquete es.mityc.facturae.ui

En este paquete se incluye la interfaz de usuario. Se permite la selección de

certificado para firmar una factura digitalmente cuando no éste no se pasa como parámetro. Esta interfaz permite la visualización de certificados disponibles, la consulta de los atributos de estos certificados, la selección de uno de ellos y la validación de los mismos vía OCSP. Los certificados listados dependen del almacén indicado / configurado.

Esta interfaz se lanza directamente desde el proceso de firma de factura, es decir,

desde el componente SignatureUtil.

14

Ilustración 2Ventana de selección / consulta de certificados

15

Configuración

Configuración del componente de firma Para configurar el componente de firma a utilizar habrá que incluir un recurso con nombre

“sign.properties” anterior al bridge (FacturaEBridge.jar) en el classpath de la aplicación. Habrá que definir la propiedad “facade.sign.class” indicando la clase que implementa la interfaz del “bridge”.

Por defecto, se utilizan los componentes de firma desarrollados por MITyC (versión 1.0). El

fichero “sign.properties” contiene:

facade.sign.class=es.mityc.javasign.bridge.comp104.SignMITyCComp10Facade

Configuración de las propiedades del API El API permite definir una serie de propiedades para adaptarlo a las necesidades del

desarrollador que quiera integrarlo en su aplicación. Para sobreescribir las propiedades por defecto del API, será necesario establecer un recurso

con nombre “/config/sign.properties” anterior al API (Facturae-API.jar) en el classpath de la aplicación.

Se encuentran disponibles las siguientes propiedades:

• store almacen al que se va acceder (por ejemplo “Explorer” = Internet Explorer) • store.param parámetro auxiliar necesario para algunos almacenes (por ejemplo el

perfil para el almacén de Mozilla) • sign.policy política de firma (por ejemplo “facturae31”)

• sign.xades.schema esquema XADES (por ejemplo “1.3.2”)

• locale.language lenguaje (por ejemplo, para español, “es”)

• locale.country país (por ejemplo, para España, “ES”)

• lookAndFeel apariencia de la ventana de selección de certificados (por ejemplo “so”

para indicar la apariencia utilizada por el sistema operativo)

• lookAndFeelTheme tema para el look&feel, cuando el valor del mismo es “metal”. Contiene un valor numérico (por ejemplo “1”)

• ocsp.server servidor OCSP

16

• ocsp.proxyused “true” o “false” en función de si se usa proxy o no

• ocsp.proxyauthenticated “true” o “false” en función de si el proxy es autenticado

• ocsp.proxyserver dirección de proxy

• ocsp.proxyport puerto del proxy

• ocsp.proxyuser usuario de proxy autenticado

• ocsp.proxypassword password de proxy autenticado

• truster.id identificador de la clase encargada de administrar la confianza (por

defecto mityc).

Las propiedades configuradas por defecto son las siguientes:

store=Explorer store.param= sign.policy=facturae31 sign.xades.schema=1.3.2 locale.language=es locale.country=ES lookAndFeel=so #It will be considered only if lookAndFeel contains "metal" lookAndFeelTheme=1 #OCSP validation ocsp.server= ocsp.proxyused= ocsp.proxyauthenticated= ocsp.proxyserver= ocsp.proxyport= ocsp.proxyuser= ocsp.proxypassword= #truster truster.id=mityc

Configuración de la imagen de cabecera de la ventana de selección de certificado

El API incluye una interfaz, compuesta por una sola ventana, para la selección de certificado.

Esta ventana incorpora una imagen superior como cabecera, que se establece en función de que el look&feel configurado sea “facturae” o cualquier otro.

17

No se recomienda modificar la imagen correspondiente al look&feel “facturae” ya que se ha realizado a medida para esta presentación. Sin embargo, si el look&feel es otro (por ejemplo “so”, sistema operativo) podría interesar cargar una imagen distinta.

Para ello, simplemente habría que establecer un nuevo recurso con nombre

“/images/topbar3.jpg” anterior al API (Facturae-API.jar) en el classpath de la aplicación. Esta nueva imagen, debería respetar las dimensiones de la imagen por defecto para no interferir en la correcta presentación de la ventana.

Configuración del sistema de logs

El API permite definir el sistema de logs a utilizar. De esta forma el desarrollador puede conectar el API con el sistema de logs utilizado en su aplicación. Para conseguirlo se hace uso de la librería de Apache commons-logging.

Para conectar el API con un sistema de logs es necesario configurar el fichero commons-

logging.properties. Para sobreescribir el existente por defecto, será necesario crear un recurso con nombre “conmmons-logging.properties” que se encuentre por delante del fichero del mismo nombre contenido en el API (Facturae-API.jar) en el classpath de la aplicación.

Por defecto, el API hace uso de log4j. El contenido del fichero commons-logging.properties

incluido en el API es el siguiente:

org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4Jlogger

En el caso de querer continuar utilizando este sistema, también es posible definir las

propiedades concretas de log4j. Para ello habrá que crear un recurso con nombre “log4j.properties” anterior al API (Facturae-API.jar) en el classpath de la aplicación

Para sobreescribir las propiedades de logs por defecto, será necesario establecer un recurso

con nombre “commons-logging.properties” anterior al incluido en el API (Facturae-API.jar) en el classpath de la aplicación.

Por defecto, el contenido del fichero log4j.properties incluido en el API es el siguiente:

log4j.rootLogger=ERROR, Consola log4j.appender.Consola=org.apache.log4j.ConsoleAppender log4j.appender.Consola.layout=org.apache.log4j.PatternLayout log4j.appender.Consola.layout.ConversionPattern=[%-5p] %c{1} --> %m%n

Configuración del lenguaje Como ya se ha mencionado con anterioridad, el API es multilenguaje. Por defecto incluye los

idiomas español e inglés. Sería posible incluir nuevos idiomas con relativa comodidad. Para ello habría que añadir los siguientes recursos:

18

• Un recurso con nombre “language/lang_xx_XX.properties”, dónde “xx” son dos

caracteres en minúsculas que indican el lenguaje utilizado, y “XX” dos caracteres en mayúsculas que indican el país. Este fichero contiene toda la traducción de las interfaces del API.

• Un recurso html con nombre “html/help_certificat

• e_xxXX.html”, dónde “xx” son dos caracteres en minúsculas que indican el lenguaje

utilizado, y “XX” dos caracteres en mayúsculas que indican el país (opcionales). Este recurso constituye una página html con la ayuda de la ventana de selección de certificados.

o Recursos de idioma de los componentes de firma. Al igual que en los casos

anteriores, habría que añadir ficheros personalizados para el idioma y país deseados.

Advertencias No es posible realizar un “unmarshal” de una factura firmada para después realizar un

“marshal”. La factura que se obtiene no es equivalente a la de partida y la firma resulta no ser válida debido al cambio en la estructura del fichero. El problema reside en que los procesos de “marshal” y “unmarshal” no guardan información de la estructura del XML.

No existe mayor problema, ya que en realidad, nunca debería realizarse un “unmarshal” para

después realizar un “marshal”. Una factura firmada no se podrá modificar nunca, por lo que si se realizara un “unmarshal” de la misma, sólo sería con propósitos de lectura y nunca de alteración.

Problema JRE La API es compatible con las máquinas virtuales JRE1.5 y JRE1.6. No obstante se ha

detectado un problema con la actualización 03 de la JRE1.6. Las librerías de JAXB en su versión 2.1 (utilizadas para el desarrollo de la API) tienen un conflicto con las librerías de JRE.

Se recomienda encarecidamente no usar la versión JRE1.6.0_03. Con la versión JRE1.6.0_07

(la más reciente durante la redacción de este documento) se soluciona el problema. En cualquier caso, si se reprodujera el problema puede solucionarse a través del mecanismo de directorio “endorsed”. Para saber más acerca de este problema y como solucionarlo, acceda al siguiente enlace:

http://java.sun.com/j2se/1.5.0/docs/guide/standards/

19

ANEXO A: USO DE EXTENSIONS

Introducción En ocasiones, el formato Facturae no consigue paliar las necesidades concretas de todos los

sectores de negocio a los que va dirigido. Por tal motivo, se optó por definir un elemento incluido en el formato y con nombre “Extensions” que permitiese la introducción flexible de datos estructurados.

Estas extensiones pueden introducirse a tres niveles:

- Lote de facturas - Datos adicionales

- Línea de factura

Existe una gran diferencia entre el elemento “Extensions” definido en el formato 3.0 con

respecto al definido en el formato 3.1/ 3.2. En el primer caso, no se realiza validación contra esquema, tan sólo se comprueba que es un elemento XML bien formado y que el espacio de nombres (atributo xmlns) es distinto al de Facturae. En el segundo caso, sí que se realiza una validación contra esquema obligatoria. En el siguiente apartado, se detallará como introducir un nuevo esquema.

Configuración En el caso de facturas con formato Facturae 3.1 / 3.2 se realiza una validación obligatoria

contra esquema del contenido del elemento “Extensions”. Por este motivo, es necesario especificarle al componente de validación de facturas, dónde se encuentra el esquema que sigue dicha extensión del formato.

Es necesario definir un fichero de propiedades que contenga los datos de los esquemas

utilizados en las extensiones. El nombre del fichero es “schemaLocationExtensions.properties” y se encuentra en la ruta externa a la API “/config/”.

Este fichero de propiedades estará formado por:

- Una propiedad fija, que contiene una lista de los esquemas introducidos separados por “;”.

EXTENSION_SCHEMAS

- Dos nuevas propiedades por cada uno de los esquemas. La primera indica la localización interna del esquema y la segunda el espacio de nombres.

EXTENSION_SCHEMA_<NOMBRE_ESQUEMA> <NOMBRE_ESQUEMA>_EXTENSION_NAMESPACE

20

Ejemplo de fichero de propiedades schemaLocationExtensions.properties que incluye dos

esquemas de extensiones: SHIPORDER y TRAVEL. EXTENSION_SCHEMA_SHIPORDER=externalResources/schemas/shiporder.xsd SHIPORDER_EXTENSION_NAMESPACE=http://www.extensions.es/shiporder EXTENSION_SCHEMA_TRAVEL=externalResources/schemas/travel.xsd TRAVEL_EXTENSION_NAMESPACE=http://www.extensions.es/travel EXTENSION_SCHEMAS=SHIPORDER;TRAVEL

Por otro lado, hay que introducir los esquemas XSD correspondientes en las rutas

especificadas en el fichero de propiedades. En este caso, en la ruta externa a la API “/externalResources/schemas/”.

Creación del elemento “Extensions” Existen dos posibilidades para crear un elemento “Extensions” (a cualquiera de los niveles que

permite el formato). La primera opción es manipular directamente el fichero XML para escribir el contenido

adecuado. La segunda opción, es más recomendable y pasa por crear la extensión desde el objeto JAVA, antes de construir el fichero XML. A continuación se detallará ésta última opción.

Para introducir las extensiones desde el objeto JAVA que representa una factura: 1. Partimos de un fichero XML que representa una factura (versión 3.0, 3.1 ó 3.2)

File f = new File (“factura.xml"); 2. Se crea una cadena de texto que contenga los datos en XML de la extensión

String s="<jarl:shiporder xmlns:jarl=\"http://www.extensions.es/shiporder\" orderid=\"33\">"+ "<orderperson>" + "Juana Batata" + "</orderperson>" + "<shipto>" + "<name>Hugo Sanchez</name>" + "<address>C/Mayor</address>" + "<city>Mexico D.F.</city>" + "<country>Mexico</country>" + "</shipto>" + "<item>" + "<title>Mister T</title>" + "<note>Enviado de Argentina</note>" + "<quantity>5</quantity>" + "<price>7.88</price>" + "</item>" +

"</jarl:shiporder>";

21

3. Se obtiene un objeto “Document” a partir del fichero que representa la factura.

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

dbf.setNamespaceAware(true); Document doc = null; try { doc = dbf.newDocumentBuilder().parse(f);

catch (ParserConfigurationException ex) {} catch (SAXException ex) {} catch (IOException ex) {} catch (IllegalArgumentException ex) {}

4. Se obtiene un objeto “Document” a partir de la cadena que representa la extensión. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

dbf.setNamespaceAware(true); Document doc2 = null; try { doc2 = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(s)));

catch (ParserConfigurationException ex) {} catch (SAXException ex) {} catch (IOException ex) {} catch (IllegalArgumentException ex) {}

5. Se importa el nodo desde el documento que contiene la factura.

Node nVal = doc.importNode(doc2.getChildNodes().item(0),true); // true = deep copy

6. Se declara e inicializa el nodo “Extensions” que se desee modificar.

* Una forma sencilla de hacerlo sería la que se muestra a continuación. Existen otros procedimientos más adecuados y fiables basados en la lectura del árbol. Queda a elección del desarrollador elegir un método u otro. Node nExt = doc.getElementsByTagName("Extensions").item(3);

7. Se añade el nodo que contiene las extensiones.

nExt.appendChild(nVal);

8. Por último habría que construir el fichero XML a partir del documento modificado doc. try { Source source = new DOMSource(doc);

File file = new File(filename); Result result = new StreamResult(file);

Transformer xformer = TransformerFactory.newInstance().newTransformer(); xformer.transform(source, result);

} catch (TransformerConfigurationException tce) { }

catch (TransformerException te) { }