--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright
+ 2009 axYus - www.axyus.com
+ 2009 C.Marchand - christophe.marchand@axyus.com
+
+ This file is part of XEMELIOS.
+
+ XEMELIOS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ XEMELIOS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with XEMELIOS; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+ <xsl:output indent="yes" encoding="UTF-8" method="xml"/>
+
+ <xsl:template match="/">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="node()">
+ <xsl:choose>
+ <xsl:when test="local-name(.) = 'parameter'">
+ <xsl:copy>
+ <xsl:attribute name="name"><xsl:value-of select="./@name"/></xsl:attribute>
+ <xsl:choose>
+ <xsl:when test="./@name = 'export.p1.max.size'">
+ <xsl:attribute name="value">3000</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="./@name = 'export.p2.max.size'">
+ <xsl:attribute name="value">7000</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="./@name = 'export.max.size'">
+ <xsl:attribute name="value">15000</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="./@name='documents-def.dir'">%basedir%/documents-def</xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="exists(./@value)"><xsl:attribute name="value"><xsl:value-of select="./@value"></xsl:value-of></xsl:attribute></xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="not(./@name = 'documents-def.dir')">
+ <xsl:apply-templates/>
+ </xsl:if>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:for-each select="@*">
+ <xsl:choose>
+ <xsl:when test="local-name(.) = 'start-time'"><xsl:attribute name="start-time">22:00</xsl:attribute></xsl:when>
+ <xsl:otherwise><xsl:attribute name="{local-name(.)}">
+ <xsl:value-of select="."/>
+ </xsl:attribute></xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <xsl:template match="comment()[string-length(.) > 50]">
+ <xsl:comment>
+ <xsl:value-of select="."/>
+ </xsl:comment>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="XEMELIOS-batch" default="usage" basedir=".">
+ <description>Builds, tests, and runs the project XEMELIOS xemelios-core</description>
+ <property file="${user.home}/.ant.properties"/>
+ <property name="compile.debug" value="true"/>
+ <xmlproperty file="component-definition-properties.xml"/>
+
+ <target name="usage">
+ <echo> Using ${ant.version} These are targets supported by this ANT build script: compile -
+ compile all .java files, except thoses in ./tmp folder. clean - deletes all compiled and
+ generated files and resources. jars - build jar files. Do not call this script directly,
+ use the one located at root of projet (in ../..) instead. </echo>
+ </target>
+
+ <target name="compile" depends="mk-output-dirs">
+ <javac srcdir="java" destdir="build/classes" debug="${compile.debug}" encoding="ISO-8859-1">
+ <classpath>
+ <!--fileset dir="lib" includes="*.jar"/-->
+ <fileset dir="../starter/build/jars" includes="*.jar"/>
+ <pathelement path="../xml-marshall/build/classes"/>
+ <pathelement path="../core/build/classes"/>
+ <pathelement path="../import-batch/build/classes"/>
+ <pathelement path="../xemelios-core/build/classes"/>
+ <pathelement path="../mysql-persistence/build/classes"/>
+ <pathelement path="../starter/build/classes"/>
+ <fileset dir="../core/lib/" includes="*.jar"/>
+ <fileset dir="../swing-utils/lib/" includes="*.jar"/>
+ <fileset dir="../xemelios-core/lib">
+ <include name="core-renderer.jar"/>
+ <include name="iText*.jar"/>
+ </fileset>
+ </classpath>
+ </javac>
+ <copy todir="build/classes">
+ <fileset dir="java">
+ <include name="**/*"/>
+ <exclude name="**/*.java"/>
+ <exclude name="**/CVS/*"/>
+ <exclude name="**/*.form"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="jars">
+ <!-- property file="component.properties"/ -->
+ <copy file="manifest/manifest.txt" tofile="build/manifest.txt">
+ <filterset>
+ <filter token="version" value="${component.release}"/>
+ <filter token="name" value="${component.name}"/>
+ </filterset>
+ </copy>
+ <jar destfile="build/jars/xemelios-batch.jar" basedir="build/classes"
+ manifest="build/manifest.txt"/>
+ </target>
+
+ <target name="clean">
+ <delete dir="build"/>
+ </target>
+
+
+ <target name="mk-output-dirs">
+ <mkdir dir="build/classes"/>
+ <mkdir dir="build/jars"/>
+ </target>
+
+ <!--target name="config" description="Genere l'arborescence de mise a jour">
+ <property file="component.properties"/>
+ <property name="component.dir" value="build/config/${component.name}/${component.release}"/>
+ <mkdir dir="${component.dir}"/>
+ <copy todir="${component.dir}">
+ <fileset dir="lib" includes="*.jar *.dll"/>
+ <fileset dir="build/jars" includes="*.jar"/>
+ <fileset dir="res" includes="*.*"/>
+ </copy>
+ <propertyfile file="${component.dir}/component.properties">
+ <entry key="description" value="Programme Xemelios"/>
+ <entry key="type" value="xemelios-updates"/>
+ <entry key="base.dest" value="${xemelios.prg}/root/lib/"/>
+ <entry key="deletes" value="${xemelios.prg}/root/documents-def/documents.xml,${xemelios.prg}/root/documents-def/etatPaye.xsl,${xemelios.prg}/root/documents-def/etatVersement.xsl,${xemelios.prg}/root/documents-def/nomenclature-import.xsl,${xemelios.prg}/root/documents-def/nomenclature-import-versement.xsl,${xemelios.prg}/root/documents-def/nomenclature-paye.xsl,${xemelios.prg}/root/documents-def/nomenclature-versement.xsl,${xemelios.prg}/root/documents-def/persistence-config/etatPaye-import-mysql.xsl,${xemelios.prg}/root/documents-def/persistence-config/etatVersement-import-mysql.xsl,${xemelios.prg}/root/documents-def/persistence-config/index.xsl,${xemelios.prg}/root/documents-def/persistence-config/paye-persistence.xml,${xemelios.prg}/root/documents-def/persistence-config/versement-persistence.xml,${xemelios.prg}/root/lib/import-batch.jar,${xemelios.prg}/root/lib/Xilize.jar,${xemelios.prg}/root/lib/cssparser-0-9-4-fs.jar,${xemelios.prg}/root/lib/looks-2.0.4.jar,${xemelios.prg}/root/lib/svgSalamander.jar,${xemelios.prg}/root/lib/itext-paulo-155.jar,${xemelios.prg}/root/setup-xemelios.zip,${xemelios.prg}/root/lib/commons-io-1.2.jar"/>
+ <entry key="log4j.xml.dest" value="${xemelios.prg}/root"/>
+ <entry key="modeleExcelHtml.xls.dest" value="${xemelios.prg}/root/resources"/>
+ <entry key="modeleExportXemelios.xls.dest" value="${xemelios.prg}/root/resources"/>
+ <entry key="modeleExportXemelios-97.xls.dest" value="${xemelios.prg}/root/resources"/>
+ <entry key="modeleExportXemelios-97SR1.xls.dest" value="${xemelios.prg}/root/resources"/>
+ <entry key="viewdoc.cmd.dest" value="${xemelios.prg}/root"/>
+ <entry key="XMLPrettyPrint.xsl.dest" value="${xemelios.prg}/root/resources"/>
+ <entry key="couri.ttf.dest" value="${xemelios.prg}/root/resources"/>
+ <entry key="configuration" value="fr.gouv.finances.cp.xemelios.patches.Core33114"/>
+ <entry key="requires" value="${component.requires}"/>
+ </propertyfile>
+ </target-->
+
+ <target name="setup">
+ <mkdir dir="build/setup"/>
+ <mkdir dir="build/setup/bin"/>
+ <mkdir dir="build/setup/lib"/>
+ <mkdir dir="build/setup/conf"/>
+ <mkdir dir="build/setup/logs"/>
+ <mkdir dir="build/setup/resources"/>
+ <mkdir dir="build/setup/documents-def"/>
+
+ <copy todir="build/setup/lib">
+ <!-- fileset dir="lib" includes="*.jar"/ -->
+ <fileset dir="build/jars" includes="*.jar"/>
+ <fileset dir="../core/build/jars" includes="*.jar"/>
+ <fileset dir="../core/lib" includes="*.jar"/>
+ <fileset dir="../import-batch/build/jars" includes="*.jar"/>
+ <fileset dir="../mysql-persistence/build/jars" includes="*.jar"/>
+ <fileset dir="../mysql-persistence/lib" includes="*.jar"/>
+ <fileset dir="../xml-marshall/build/jars" includes="*.jar"/>
+ <fileset dir="../xemelios-core/build/jars" includes="*.jar"/>
+ <fileset dir="../xemelios-core/lib">
+ <include name="core-renderer.jar"/>
+ <include name="iText*.jar"/>
+ </fileset>
+ <fileset dir="../swing-utils/lib" includes="swing-layout-1.0.jar"/>
+ <fileset dir="../starter/build/jars" includes="xemelios.jar"/>
+ <fileset dir="../auth-std-db/build/jars" includes="*.jar"/>
+ <fileset dir="../edmn/build/jars" includes="*.jar"/>
+ <fileset dir="../cg-etat/build/jars" includes="*.jar"/>
+ <fileset dir="../cg-colloc/build/jars" includes="*.jar"/>
+ </copy>
+ <copy todir="build/setup/conf">
+ <fileset dir="resources" includes="log4j*,*.properties"/>
+ </copy>
+ <copy todir="build/setup/bin">
+ <fileset dir="resources" includes="*.sh,*.bat"/>
+ </copy>
+ <copy todir="build/setup/resources">
+ <fileset dir="resources" includes="*.xls"/>
+ </copy>
+ <copy todir="build/setup/documents-def">
+ <fileset dir="../carte-achat/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../cfg-paye/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../cg-colloc/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../edmn/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../ertn/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../erar/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../facture-depense/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../facture-recette/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../pes-aller/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../pes-facture/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../quittancement/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../rapport/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../versement/conf" includes="**/*" excludes="**/CVS"/>
+ <fileset dir="../cg-etat/conf" includes="**/*" excludes="**/CVS"/>
+ </copy>
+ <xslt style="batch-conf-maker.xsl" in="conf/batch-conf.xml" out="build/setup/conf/batch-conf.xml"/>
+ <fixcrlf file="build/setup/conf/batch-conf.xml" eol="dos"/>
+ <zip destfile="build/xemelios-batches.zip" basedir="build/setup" compress="true"
+ includes="**/*" level="9"/>
+ <copy todir="../../build" file="build/xemelios-batches.zip"/>
+ </target>
+ <target name="setup-CdC" depends="setup">
+ <delete file="build/xemelios-batches.zip"/>
+ <delete file="build/setup/conf/mysql.properties"/>
+ <delete file="build/setup/conf/batch-conf.xml"/>
+ <xslt style="clients/CdC/batch-conf-maker.xsl" in="conf/batch-conf.xml" out="build/setup/conf/batch-conf.xml"/>
+ <copy file="clients/CdC/mysql.properties" todir="build/setup/conf" overwrite="yes"/>
+ <zip destfile="build/xemelios-batches.zip" basedir="build/setup" compress="true"
+ includes="**/*" level="9"/>
+ <copy todir="../../build" file="build/xemelios-batches.zip" overwrite="true"/>
+ </target>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright
+ 2009 axYus - www.axyus.com
+ 2009 C.Marchand - christophe.marchand@axyus.com
+
+ This file is part of XEMELIOS.
+
+ XEMELIOS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ XEMELIOS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with XEMELIOS; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+ <xsl:output indent="yes" encoding="UTF-8" method="xml"/>
+
+ <xsl:template match="/">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="node()">
+ <xsl:choose>
+ <xsl:when test="local-name(.) = 'parameter'">
+ <xsl:copy>
+ <xsl:attribute name="name"><xsl:value-of select="./@name"/></xsl:attribute>
+ <xsl:choose>
+ <xsl:when test="./@name = 'export.p1.max.size'">
+ <xsl:attribute name="value">3000</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="./@name = 'export.p2.max.size'">
+ <xsl:attribute name="value">10000</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="./@name = 'export.max.size'">
+ <xsl:attribute name="value">65000</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="./@name='documents-def.dir'">%basedir%/documents-def</xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="exists(./@value)"><xsl:attribute name="value"><xsl:value-of select="./@value"></xsl:value-of></xsl:attribute></xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="not(./@name = 'documents-def.dir')">
+ <xsl:apply-templates/>
+ </xsl:if>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:for-each select="@*">
+ <xsl:choose>
+ <xsl:when test="local-name(.) = 'start-time'"><xsl:attribute name="start-time">21:00</xsl:attribute></xsl:when>
+ <xsl:otherwise><xsl:attribute name="{local-name(.)}">
+ <xsl:value-of select="."/>
+ </xsl:attribute></xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <xsl:template match="comment()[string-length(.) > 50]">
+ <xsl:comment>
+ <xsl:value-of select="."/>
+ </xsl:comment>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+driver.class=com.mysql.jdbc.Driver\r
+database.url=jdbc:mysql://75-SE-1051/xemelios?jdbcCompliantTruncation=false&dumpQueriesOnException=true\r
+user=xemelios\r
+password=Am/x/W<4:\r
+validation.query=SELECT 1
+max.active=25
+max.wait=8
+
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="../../defs/technical-component-definition.xsd">
+ <name>batch</name>
+ <description>Batchs pour les traitements asynchrones de l'application Web</description>
+ <release>5.0.0.1</release>
+ <url>http://xemelios.org/updatesV5/batch</url>
+ <type>COMPOSANT</type>
+ <destination>
+ <base>${xemelios.root}/documents-def/</base>
+ <file>
+ <name>${component.name}.html</name>
+ <dest>${xemelios.root}/help/documents</dest>
+ </file>
+ <file>
+ <name>${component.name}.jar</name>
+ <dest>${xemelios.root}/lib</dest>
+ </file>
+ </destination>
+ <requires>
+ <component-ref url="http://xemelios.org/updatesV5/starter" release="5.0.0.0"/>
+ <component-ref url="http://xemelios.org/updatesV5/core" release="5.0.0.12"/>
+ <!-- pour les exports -->
+ <component-ref url="http://xemelios.org/updatesV5/xemelios-core" release="5.0.0.0"/>
+ <component-ref url="http://xemelios.org/updatesV5/swing-utils" release="5.0.0.0"/>
+ <component-ref url="http://xemelios.org/updatesV5/mysql-persistence" release="5.0.0.11"/>
+ </requires>
+ <release-notes>
+ <release v="5.0.0.1">
+ <note visibility="public">Ajout du batch de gestion des droits des utilisateurs pour la CdC</note>
+ <note visibility="dev">Passage du user à l'importeur d'archive</note>
+ </release>
+ </release-notes>
+</component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+ Copyright
+ 2009 axYus - www.axyus.com
+ 2009 C.Marchand - christophe.marchand@axyus.com
+
+ This file is part of XEMELIOS.
+
+ XEMELIOS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ XEMELIOS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with XEMELIOS; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+-->
+
+<batches stop-listen-port="8006" allowedStoppers="127.0.0.1,*" info-listen-port="8007">
+ <!--
+ stop-listen-port is the TCP-IP port where the batch listens to to be stopped
+ info-listen-port is the port where you can ask for informations. Protocol is HTTP. http://server:<info-listen-port> displays detailed informations on running batch tasks
+ -->
+ <!--
+ Periodicity is described by a quantity immediatly followed by a unit.
+ Valid units are
+ s: second
+ m: minute
+ h: hour
+ d: day
+
+ For example :
+ 12s starts batch every 12 seconds
+ 2m starts batch every 2 minutes
+ 1d starts batch once a day
+
+ Batches always start about 1 second after batch-runner starts
+ -->
+ <parameter name="documents-def.dir">%basedir%/src/carte-achat/conf,%basedir%/src/cfg-paye/conf,%basedir%/src/facture-depense/conf,%basedir%/src/facture-recette/conf,%basedir%/src/pes-aller/conf,%basedir%/src/pes-facture/conf,%basedir%/src/quittancement/conf,%basedir%/src/rapport/conf,%basedir%/src/versement/conf,%basedir%/src/edmn/conf,%basedir%/src/erar/conf,%basedir%/src/cg-colloc/conf,%basedir%/src/cg-etat/conf,%basedir%/src/ertn/conf</parameter>
+ <!--
+ Ce batch verifie que l'ensemble des informations necessaires à l'import sont bien disponibles.
+ Il peut avoir a decompresser les fichiers déposés, éventuellement les parser (au moins le début du fichier).
+ Son temps d'exécution est très limité.
+ Si des informations sont manquantes, c'est a son initiative que l'utilisateur se verra poser des questions.
+ Il est donc important que ce batch tourne régulièrement, pour que l'utilisateur ait l'impression d'une
+ bonne interactivité.
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.imports.ImportChecker" periodicity="2m">
+ <parameter name="max.concurrent.threads" value="5"/>
+ </batch>
+ <!--
+ Ce batch réalise les imports. Il peut ne tourner que toutes les heures, mais ne doit pas avoir trop d'executions
+ concurrentes. Le temps d'execution est strictement proportionnel à la taille des fichiers à importer.
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.imports.Importer" periodicity="2m">
+ <parameter name="max.concurrent.threads" value="5"/>
+ </batch>
+ <!--
+ Ce batch est chargé du nettoyage après import. Les fichiers importés sont supprimés, et les demandes d'import
+ non satisfaites depuis un délai donné (par exemple si des informations sont manquantes) sont supprimées.
+ Ce batch peut ne tourner qu'une fois par jour, et a une durée d'execution faible.
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.imports.PostImportCleaner" periodicity="1d">
+ <parameter name="max.concurrent.threads" value="5"/>
+ </batch>
+
+ <!--
+ Ce traitement a en charge de réinitialiser les statuts des exports qui ont été interrompus par un arrêt
+ des batchs.
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.exports.ExportInitiator" />
+ <!--
+ Ce batch a en charge d'évaluer les demandes d'export pour décider de la priorité à leur affecter.
+ En fonction de la taille des exports (en nombre d'éléments importés), il affecte la priorité 1, 2 ou 3.
+ Il peut aussi annuler un export si le volume a exporter est trop important.
+ Ce batch a une duree d'execution très courte, et n'accède à aucun fihcier (uniquement des accès en base de donnée.
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.exports.ExportEvaluator" periodicity="30s">
+ <parameter name="max.concurrent.threads" value="1"/>
+ <parameter name="export.p1.max.size" value="2000"/>
+ <parameter name="export.p2.max.size" value="17000"/>
+ <parameter name="export.max.size" value="65000"/>
+ </batch>
+ <!--
+ Ce batch réalise les exports de priorit 1, c'est à dire les exports avec les plus petits volumes.
+ On utilise en général l'exporteur JxlExporter, qui génère directement des fichiers Excel, mais qui
+ ne supporte pas les gros volumes de données.
+ On peut lui associer un post-traitement, pour Zipper le fichier généré, avant que l'utilisateur ne le télécharge,
+ mais cela n'a rien d'obligatoire.
+ Etant donné que Excel (l'application) n'est pas sollicité, on peut lancer plusieurs traitements en même temps,
+ mais il ne faut pas en lancer trop non plus, car JxlExporter peut être gourmant en mémoire.
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.exports.ExportRunner" periodicity="5m">
+ <parameter name="max.concurrent.threads" value="5"/>
+ <parameter name="priority.level" value="1"/>
+ <parameter name="exporter.class.name">fr.gouv.finances.cp.xemelios.export.FullXlsExporter</parameter>
+ <post-processor>fr.gouv.finances.dgfip.xemelios.batch.exports.postProcessors.Zipper</post-processor>
+ </batch>
+ <!--
+ Ce batch réalise les exports de priorité 2.
+ Il utilise généralement l'exporteur HtmlTableExporter qui génère un fichier HTML par feuille Excel. Ces
+ différents fichiers doivent être ensuite reconstitués en un unique fichier Excel - c'est le rôle de la macro
+ contenue dans le fichier Excel associé.
+ On peut faire tourner cette macro côté serveur : dans ce cas il faut associer un post-traitement
+ ExcelRunner, qui nécessite la présence sur le serveur d'un Excel 2003 minimum, en configurant le niveau de
+ sécurité à bas pour l'exécution des macros.
+ On peut aussi associer un Zipper pour compresser l'export à envoyer à l'utilisateur.
+ Si on ne veut pas que la reconstruction du fichier Excel se fasse côté serveur, il faut alors impérativement
+ associer un post-traitement Zipper pour compresser dans une seule archive zip tous les fichiers générés.
+ Lorsque l'utilisateur téléchargera son fichier zip, il le décompressera sur son disque local, ouvrira le
+ fichier Excel, et la macro de reconstruction s'executera.
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.exports.ExportRunner" periodicity="1h">
+ <parameter name="max.concurrent.threads" value="2"/>
+ <parameter name="priority.level" value="2"/>
+ <parameter name="exporter.class.name">fr.gouv.finances.cp.xemelios.export.FullXlsExporter</parameter>
+ <post-processor>fr.gouv.finances.dgfip.xemelios.batch.exports.postProcessors.Zipper</post-processor>
+ </batch>
+ <!--
+ cf. ci-dessus, avec une priorité 3
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.exports.ExportRunner" periodicity="1d" start-time="21:00">
+ <parameter name="max.concurrent.threads" value="1"/>
+ <parameter name="priority.level" value="3"/>
+ <parameter name="exporter.class.name">fr.gouv.finances.cp.xemelios.export.FullXlsExporter</parameter>
+ <post-processor>fr.gouv.finances.dgfip.xemelios.batch.exports.postProcessors.Zipper</post-processor>
+ </batch>
+ <!--
+ Ce batch a en charge le nettoyage des jobs d'export : suppression des fichiers téléchargés. Il est possible
+ de paramétrer le temps de conservation des fichiers générés (en jours).
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.exports.ExportCleaner" periodicity="1d">
+ <parameter name="max.concurrent.threads" value="1"/>
+ <parameter name="clean.delay" value="20"/>
+ </batch>
+ <!--
+ Ce batch a en charge de déterminer, pour chaque type de document,
+ la liste des travaux de génération de PDF
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.pdf.PdfPreparator" periodicity="1h">
+ <parameter name="max.concurrent.threads" value="1"/>
+ <parameter name="documents" value="cg-etat"/>
+ </batch>
+ <!--
+ Ce batch a en charge de produire le PDF associé à un type de document
+ -->
+ <batch class="fr.gouv.finances.dgfip.xemelios.batch.pdf.PdfCreator" periodicity="2h">
+ <parameter name="document.id" value="cg-etat"/>
+ <parameter name="element.id" value="BalanceGenerale"/>
+ </batch>
+
+ <!--
+ Ce batch permet d'attribuer et d'enlever des droits à des utilisateurs.
+ On peut en déclarer autant qu'on veut, avec des targets différents.
+ A ce jour, les seuls targets suportés sont SPL et ETAT
+ -->
+ <batch class="fr.ccomptes.xemelios.credentials.CredentialSetter" periodicity="2m">
+ <parameter name="input">/home/cmarchand/devel/CdC-GestionDroits/data/input</parameter>
+ <parameter name="output">/home/cmarchand/devel/CdC-GestionDroits/data/output</parameter>
+ <parameter name="target">SPL</parameter>
+ <parameter name="input.separator" value=";"/>
+ <parameter name="input.encoding" value="UTF-8"/>
+ <parameter name="ldap.config.file" value="/home/cmarchand/Professionnel/CdC/ldap.config.properties"/>
+ </batch>
+</batches>
--- /dev/null
+/*
+ * Copyright
+ * 2011 axYus - www.axyus.com
+ * 2011 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of Gestion-Droits.
+ *
+ * Gestion-Droits is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Gestion-Droits is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Gestion-Droits; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package fr.ccomptes.xemelios.credentials;
+
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.TreeSet;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import org.apache.log4j.Logger;
+
+/**
+ * This class defines credentials
+ * @author cmarchand
+ */
+public class CredentialSetter extends Batch {
+ public static final String INPUT = "input";
+ public static final String OUTPUT = "output";
+ public static final String INPUT_ENCODING = "input.encoding";
+ public static final String INPUT_SEPARATOR = "input.separator";
+ public static final String DATE_FORMAT = "dd/MM/yyyy";
+ public static final String TARGET = "target";
+ public static final String LDAP_CONFIG_FILE = "ldap.config.file";
+ public static final String TOUS = "Tous";
+ private File inputDir, outputDir;
+ private String encoding;
+ private String separator;
+ private TARGETS target;
+ private Properties ldapProperties;
+ private static enum TARGETS { SPL, ETAT };
+
+ @Override
+ protected void doProcess() throws Exception {
+ run();
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return null;
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "Gestion Droits";
+ }
+
+ @Override
+ public String getInformations() {
+ return null;
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+ /**
+ * Acknowledgement status
+ */
+ public enum ACK_STATUS { OK, KO };
+ private static final Logger logger = Logger.getLogger(CredentialSetter.class);
+// private Initializer initer = null;
+ private SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+
+ /**
+ * Creates a new process
+ * @param initializer
+ */
+ public CredentialSetter(String[] args) {
+ super(args);
+// this.initer = initializer;
+// initialize();
+ }
+
+ @Override
+ protected void initialize() {
+ inputDir = new File(getProps().getProperty(INPUT));
+ outputDir = new File(getProps().getProperty(OUTPUT));
+ outputDir.mkdirs();
+ separator = getProps().getProperty(INPUT_SEPARATOR);
+ encoding = getProps().getProperty(INPUT_ENCODING);
+ String t = getProps().getProperty(TARGET);
+ this.target = t.equals("SPL") ? TARGETS.SPL : TARGETS.ETAT;
+ File fLdapConfig = new File(getProps().getProperty(LDAP_CONFIG_FILE));
+ if(fLdapConfig.exists()) {
+ try {
+ ldapProperties = new Properties();
+ FileInputStream fis = new FileInputStream(fLdapConfig);
+ ldapProperties.load(fis);
+ fis.close();
+ } catch(Exception ex) {
+ logger.error("while parsing "+fLdapConfig.getAbsolutePath());
+ }
+ }
+ if(ldapProperties==null) throw new RuntimeException("Property "+LDAP_CONFIG_FILE+" not set !");
+ }
+
+ /**
+ * Creates or removes credentials
+ * @throws RuntimeException
+ */
+ public void run() throws RuntimeException {
+ FileFilter ff = new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ return !pathname.isDirectory();
+ }
+ };
+ File[] inputFiles = inputDir.listFiles(ff);
+ while(inputFiles.length>0) {
+ try {
+ String fileName = inputFiles[0].getName();
+ BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFiles[0]),encoding));
+ String line = br.readLine();
+ int numLine = 0;
+ while(line!=null) {
+ parseLine(line, numLine, fileName);
+ line = br.readLine();
+ numLine++;
+ }
+ inputFiles[0].renameTo(new File(new File(inputFiles[0].getParentFile(),"done"),inputFiles[0].getName()));
+// inputFiles[0].delete();
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ inputFiles = inputDir.listFiles(ff);
+ }
+ }
+ protected void parseLine(String line, int numLigne, String fileName) {
+ String[] rec = line.split(separator, -1);
+ if(rec.length!=6) {
+ writeAck(fileName, numLigne, ACK_STATUS.KO, rec.length+" fields found, 6 expected", line);
+ logger.error("parseLine:", new ParsingException(fileName+" - row "+numLigne+" : incorrect number of fields :"+rec.length+" founds, 6 were expected"));
+ return;
+ }
+ String checkMsg = checkLineFormat(rec);
+ if(checkMsg!=null) {
+ writeAck(fileName, numLigne, ACK_STATUS.KO, checkMsg, line);
+ logger.error("parseLine:",new ParsingException(fileName+" - row "+numLigne+" "+checkMsg));
+ return;
+ }
+ UsersToSet users = rec[2]!=null ? new UsersToSet(rec[2]) : null;
+ CollectivitesToSet collectivites = rec[3]!=null ? new CollectivitesToSet(rec[3]) : null;
+ DocumentsToSet documents = rec[4]!=null ? new DocumentsToSet(rec[4]) : null;
+ doGrants(users, collectivites, documents, rec[5], rec[1]);
+ writeAck(fileName, numLigne, ACK_STATUS.OK, null, line);
+ }
+ /**
+ * Checks {@literal line} format.
+ * @param the splitted line
+ * @return {@literal null} if format is correct and all fields values are acceptable, or error message
+ */
+ public String checkLineFormat(String[] rec) {
+ // is this a date ?
+ try {
+ sdf.parse(rec[0]);
+ } catch(ParseException pEx) {
+ return rec[0] +" n'est pas une date valide au format "+DATE_FORMAT;
+ }
+ if(!"O".equals(rec[1]) && !"F".equals(rec[1]))
+ return rec[1]+" n'est pas pas une action valide : attendu [O|F]";
+ // no control on users
+ // no control on collectivite
+ // no control on document-type (we do not have the information here)
+ // we check if profil exists
+ Connection con = null;
+ PreparedStatement ps = null;
+ if(rec[5]!=null && rec[5].length()>0) {
+ try {
+ con = PoolManager.getInstance().getConnection();
+ ps = con.prepareStatement("SELECT PRF_CODE FROM AUTH_PROFIL WHERE PRF_CODE=?");
+ ps.setString(1, rec[5]);
+ ResultSet rs = ps.executeQuery();
+ boolean found = rs.next();
+ rs.close();
+ if(!found) {
+ return rec[5]+" is not a known profil";
+ }
+ } catch(SQLException sqlEx) {
+ logger.error("checking if PROFIL exsists:",sqlEx);
+ } finally {
+ if(ps!=null) {
+ try {
+ ps.close();
+ } catch(SQLException ignoreIt) {}
+ }
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ con = null;
+ }
+ }
+ }
+ return null;
+ }
+ /**
+ * Writed acknowledgment file
+ * @param originalFileName The input file name
+ * @param numLigne The input file line number
+ * @param status {@link #ACK_STATUS}
+ * @param message
+ * @param originalLine
+ * @throws RuntimeException if message contains a separator char
+ */
+ protected void writeAck(String originalFileName, int numLigne, ACK_STATUS status, String message, String originalLine) throws RuntimeException {
+ int lastDot = originalFileName.lastIndexOf(".");
+ String baseFileName = null;
+ String extension = null;
+ if(lastDot>=0) {
+ baseFileName = originalFileName.substring(0, lastDot);
+ extension = originalFileName.substring(lastDot);
+ } else {
+ baseFileName = originalFileName;
+ extension = "";
+ }
+ String newName = baseFileName+"-"+numLigne+extension;
+ File targetFile = new File(outputDir,newName);
+ try {
+ FileOutputStream fos = new FileOutputStream(targetFile);
+ OutputStreamWriter fw = new OutputStreamWriter(fos, encoding);
+ fw.write(status==ACK_STATUS.KO?"KO":"OK");
+ fw.write(";");
+ if(message!=null) fw.write(message);
+ fw.write(";");
+ fw.write(originalLine);
+ fw.flush();
+ fw.close();
+ } catch(IOException ioEx) {
+ logger.error("writeAck:",ioEx);
+ }
+ }
+
+ /**
+ * Query the LDAP directory to retrieve users that belongs to this CRC
+ * @param crcCode
+ * @return
+ */
+ protected List<Long> getUsersFromCRC(String crcCode) {
+ TreeSet<String> ret = new TreeSet<String>();
+ Hashtable<String,String> ldapEnv = new Hashtable<String, String>();
+ ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ ldapEnv.put(Context.PROVIDER_URL, "ldap://" + ldapProperties.getProperty("server") + ":" + ldapProperties.getProperty("port"));
+ ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
+ ldapEnv.put(Context.SECURITY_PRINCIPAL, ldapProperties.getProperty("principal"));
+ ldapEnv.put(Context.SECURITY_CREDENTIALS, ldapProperties.getProperty("credentials"));
+
+ try {
+ LdapContext ctx = new InitialLdapContext(ldapEnv,null);
+
+ SearchControls searchCtls = new SearchControls();
+ searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ String searchFilter = ldapProperties.getProperty("filter");
+ // cela peut aussi être Assistants ou Conseillers
+ String searchBase = ldapProperties.getProperty("search.base").replaceAll("<GROUP>", crcCode);
+ String[] roles = ldapProperties.getProperty("roles").split(",",0);
+// int found=0;
+ for(String role:roles) {
+ String localBase = searchBase.replaceAll("<ROLE>", role);
+ NamingEnumeration<SearchResult> answer = ctx.search(localBase, searchFilter, searchCtls);
+ String returnedAtts[] = {"members"};
+ searchCtls.setReturningAttributes(returnedAtts);
+ while(answer.hasMore()) {
+// found++;
+ SearchResult sr = (SearchResult) answer.next();
+ Attributes attrs = sr.getAttributes();
+ if (attrs != null) {
+ Attribute at = attrs.get(ldapProperties.getProperty("attribute.for.login"));
+ ret.add(at.getAll().next().toString());
+ }
+ }
+ }
+ ctx.close();
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ ArrayList<Long> lst = new ArrayList<Long>();
+ for(Iterator<String> it=ret.iterator();it.hasNext();) {
+ lst.add(getUserIdFromLogin(it.next()));
+ }
+ return lst;
+
+ }
+ /**
+ * Query various dictionnaries to get the collectivites attached to the specified CRC
+ * @param crcCode
+ * @return
+ */
+ protected List<String> getCollectivitesFromCRC(String crcCode) {
+ ArrayList<String> ret = new ArrayList<String>();
+ switch(target) {
+ case ETAT: {
+ // in ETAT, we always get the codic, and never the CRC or room num...
+ ret.add(crcCode);
+ }
+ default: {
+ Connection con = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ ps = con.prepareStatement("SELECT DISTINCT DEPT_CODE FROM CRC_REFERENTIEL WHERE CRC_CODE=?");
+ ps.setString(1,crcCode);
+ rs = ps.executeQuery();
+ ArrayList<String> depts = new ArrayList<String>();
+ while(rs.next()) {
+ depts.add(rs.getString(1));
+ }
+ rs.close(); rs = null;
+ ps.close(); ps = null;
+ StringBuilder sb = new StringBuilder();
+ for(String dept:depts) sb.append("CODIC LIKE '").append(dept).append("%' OR ");
+ for(int i=0;i<4;i++) sb.deleteCharAt(sb.length()-1);
+ ps = con.prepareStatement("SELECT DISTINCT ID_COLL FROM REF_COLL_SPL_COLLECTIVITESSPL_COLL_IX WHERE "+sb.toString());
+ rs = ps.executeQuery();
+ while(rs.next())
+ ret.add(rs.getString(1));
+ } catch(SQLException sqlEx) {
+ logger.error("getCollectivitesFromCRC:",sqlEx);
+ } finally {
+ if(rs!=null) { try { rs.close(); } catch(SQLException sqlEx) {} }
+ if(ps!=null) { try { ps.close(); } catch(SQLException sqlEx) {} }
+ if(con!=null) { PoolManager.getInstance().releaseConnection(con); }
+ }
+ }
+ }
+ return ret;
+ }
+ private void doGrants(UsersToSet users, CollectivitesToSet collectivites, DocumentsToSet documents, String profil, String action) {
+ if(users.all) {
+ Connection con = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ ps = con.prepareStatement("SELECT UTI_ID FROM AUTH_UTILISATEUR");
+ rs = ps.executeQuery();
+ while(rs.next()) {
+ grantsUser(rs.getLong(1), collectivites, documents, profil, action);
+ }
+ } catch(SQLException sqlEx) {
+ logger.error("doGrants:",sqlEx);
+ } finally {
+ if(rs!=null) try { rs.close(); rs = null; } catch(SQLException sqlEx) {}
+ if(ps!=null) try { ps.close(); ps = null; } catch(SQLException sqlEx) {}
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ con = null;
+ }
+ }
+ } else {
+ for(Long user: users.users) {
+ grantsUser(user, collectivites, documents, profil, action);
+ }
+ }
+ }
+ private void grantsUser(Long user, CollectivitesToSet collectivites, DocumentsToSet documents, String profil, String action) {
+ Connection con = null;
+ PreparedStatement ps = null;
+ PreparedStatement ps2 = null;
+ ResultSet rs = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ if("F".equals(action)) {
+ if(collectivites!=null) {
+ if(collectivites.all) {
+ ps = con.prepareStatement("DELETE FROM AUTH_HAB_COL WHERE UTI_ID=?");
+ ps.setLong(1, user);
+ ps.executeUpdate();
+ ps.close();
+ ps = con.prepareStatement("UPDATE AUTH_UTILISATEUR SET UTI_ALL_COL=0 WHERE UTI_ID=?");
+ ps.setLong(1,user);
+ ps.executeUpdate();
+ ps.close();
+ ps = null;
+ } else {
+ ps = con.prepareStatement("DELETE FROM AUTH_HAB_COL WHERE UTI_ID=? AND COL_CLEF=?");
+ ps.setLong(1, user);
+ for(String coll:collectivites.collectivites) {
+ ps.setString(2,coll);
+ ps.executeUpdate();
+ }
+ ps.close();
+ ps = null;
+ }
+ }
+ if(profil!=null) {
+ ps = con.prepareStatement("DELETE FROM AUTH_UTI_PRF WHERE UTI_ID=? AND PRF_CODE=?");
+ ps.setLong(1, user);
+ ps.setString(2, profil);
+ ps.executeUpdate();
+ ps.close(); ps = null;
+ }
+ if(documents!=null) {
+ if(documents.all) {
+ ps = con.prepareStatement("DELETE FROM AUTH_HAB_DOC WHERE UTI_ID=?");
+ ps.setLong(1, user);
+ ps.executeUpdate();
+ ps.close();
+ ps = con.prepareStatement("UPDATE AUTH_UTILISATEUR SET UTI_ALL_DOC=0 WHERE UTI_ID=?");
+ ps.setLong(1, user);
+ ps.executeUpdate();
+ ps.close(); ps = null;
+ } else {
+ ps = con.prepareStatement("DELETE FROM AUTH_HAB_DOC WHERE UTI_ID=? AND DOC_CODE=?");
+ ps.setLong(1, user);
+ for(String docId: documents.documents) {
+ ps.setString(2,docId);
+ ps.executeUpdate();
+ }
+ ps.close();
+ ps = null;
+ }
+ }
+ } else {
+ // open rights
+ if(collectivites.all) {
+ ps = con.prepareStatement("UPDATE AUTH_UTILISATEUR SET UTI_ALL_COL=1 WHERE UTI_ID=?");
+ ps.setLong(1,user);
+ ps.executeUpdate();
+ ps.close();
+ ps = null;
+ } else {
+ ps2 = con.prepareStatement("SELECT 1 FROM AUTH_HAB_COL WHERE UTI_ID=? AND COL_CLEF=?");
+ ps = con.prepareStatement("INSERT INTO AUTH_HAB_COL (UTI_ID, TID_CODE, COL_CLEF) VALUES (?,?,?)");
+ ps2.setLong(1, user);
+ ps.setLong(1, user);
+ ps.setString(2, target==TARGETS.ETAT?"CODIC":"SIRET");
+ for(String coll:collectivites.collectivites) {
+ ps2.setString(2,coll);
+ rs = ps2.executeQuery();
+ if(rs.next()) {
+ // nothing to do
+ } else {
+ ps.setString(3,coll);
+ ps.executeUpdate();
+ }
+ rs.close();
+ rs = null;
+ }
+ ps2.close(); ps2 = null;
+ ps.close(); ps = null;
+ }
+ // profils
+ ps = con.prepareStatement("SELECT UTI_ALL_FONC FROM AUTH_UTILISATEUR WHERE UTI_ID=?");
+ ps.setLong(1,user);
+ rs = ps.executeQuery();
+ if(rs.next()) {
+ if(rs.getInt(1)==0) {
+ rs.close(); rs = null;
+ ps.close(); ps = null;
+ ps = con.prepareStatement("SELECT 1 FROM AUTH_UTI_PRF WHERE UTI_ID=? AND PRF_CODE=?");
+ ps.setLong(1,user);
+ ps.setString(2,profil);
+ rs = ps.executeQuery();
+ if(!rs.next()) {
+ rs.close(); rs = null;
+ ps.close(); ps = null;
+ ps = con.prepareStatement("INSERT INTO AUTH_UTI_PRF (UTI_ID, PRF_CODE) VALUES (?,?)");
+ ps.setLong(1,user);
+ ps.setString(2,profil);
+ ps.executeUpdate();
+ ps.close(); ps =null;
+ } else {
+ rs.close(); rs = null;
+ }
+ }
+ } else {
+ // it should never happen, we have ensured that user exists
+ rs.close(); rs = null;
+ }
+ ps.close(); ps = null;
+ // documents
+ if(documents.all) {
+ ps = con.prepareStatement("UPDATE AUTH_UTILISATEUR SET UTI_ALL_DOC=1 WHERE UTI_ID=?");
+ ps.setLong(1,user);
+ ps.executeUpdate();
+ ps.close();
+ ps = null;
+ } else {
+ ps2 = con.prepareStatement("SELECT 1 FROM AUTH_HAB_DOC WHERE UTI_ID=? AND DOC_CODE=?");
+ ps = con.prepareStatement("INSERT INTO AUTH_HAB_DOC (UTI_ID, DOC_CODE) VALUES (?,?)");
+ ps2.setLong(1, user);
+ ps.setLong(1, user);
+ for(String docId:documents.documents) {
+ ps2.setString(2,docId);
+ rs = ps2.executeQuery();
+ if(rs.next()) {
+ // nothing to do
+ } else {
+ ps.setString(2,docId);
+ ps.executeUpdate();
+ }
+ rs.close();
+ rs = null;
+ }
+ ps2.close(); ps2 = null;
+ ps.close(); ps = null;
+ }
+ }
+ } catch(SQLException sqlEx) {
+ logger.error("grantsUser:",sqlEx);
+ } finally {
+ if(rs!=null) try { rs.close(); rs = null; } catch(SQLException sqlEx) {}
+ if(ps2!=null) try { ps2.close(); ps2 = null; } catch(SQLException sqlEx) {}
+ if(ps!=null) try { ps.close(); ps = null; } catch(SQLException sqlEx) {}
+ if(con!=null) { PoolManager.getInstance().releaseConnection(con); con = null; }
+ }
+ }
+ private Long getUserIdFromLogin(String login) {
+ Connection con = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ ps = con.prepareStatement("SELECT UTI_ID FROM AUTH_UTILISATEUR WHERE UTI_LOGIN=?");
+ ps.setString(1,login);
+ rs = ps.executeQuery();
+ if(rs.next()) {
+ return rs.getLong(1);
+ } else {
+ // we must create it
+ rs.close();
+ ps.close();
+ ps = con.prepareStatement("INSERT INTO AUTH_UTILISATEUR (UTI_LOGIN,ACTIF,ALL_FONC, ALL_DOC, ALL_COL) VALUES (?,1,0,0,0)");
+ ps.setString(1,login);
+ ps.executeUpdate();
+ ps.close();
+ ps = con.prepareStatement("SELECT MAX(UTI_ID) FROM AUTH_UTILISATEUR WHERE UTI_LOGIN=?");
+ ps.setString(1,login);
+ rs = ps.executeQuery();
+ long userId = 0L;
+ if(rs.next())
+ userId = rs.getLong(1);
+ rs.close();
+ ps = con.prepareStatement("INSERT INTO AUTH_UTI_PRF (UTI_ID,ACTIF,PRF_CODE) VALUES (?,'CONNECT')");
+ ps.setLong(1,userId);
+ ps.executeUpdate();
+ ps.close();
+ return userId;
+ }
+ } catch(SQLException sqlEx) {
+ logger.error("grantsUser:",sqlEx);
+ } finally {
+ if(rs!=null) try { rs.close(); rs = null; } catch(SQLException sqlEx) {}
+ if(ps!=null) try { ps.close(); ps = null; } catch(SQLException sqlEx) {}
+ if(con!=null) { PoolManager.getInstance().releaseConnection(con); con = null; }
+ }
+ return 0L;
+ }
+ private class UsersToSet {
+ boolean all = false;
+ ArrayList<Long> users = null;
+ public UsersToSet(String spec) {
+ super();
+ users = new ArrayList<Long>();
+ String[] items = spec.split(",");
+ for(String item:items) {
+ if(TOUS.equals(item)) {
+ all = true;
+ users.clear();
+ return;
+ } else if(item.indexOf('@')>=0) {
+ users.addAll(getUsersFromCRC(item));
+ } else {
+ // we need to query LDAP for users in that CRC
+ users.add(getUserIdFromLogin(item));
+ }
+ }
+ }
+ }
+ private class CollectivitesToSet {
+ private boolean all;
+ private ArrayList<String> collectivites;
+ public CollectivitesToSet(String spec) {
+ super();
+ collectivites = new ArrayList<String>();
+ String[] items = spec.split(",");
+ for(String item: items) {
+ if(TOUS.equals(item)) {
+ all = true;
+ collectivites.clear();
+ return;
+ } else if(item.indexOf('@')==0) {
+ // it's a CRC
+ collectivites.addAll(getCollectivitesFromCRC(item));
+ } else {
+ collectivites.add(item);
+ }
+ }
+ }
+ }
+ private class DocumentsToSet {
+ private boolean all = false;
+ private TreeSet<String> documents = null;
+ public DocumentsToSet(String spec) {
+ super();
+ documents = new TreeSet<String>();
+ String[] items = spec.split(",");
+ for(String item:items) {
+ if(TOUS.equals(item)) {
+ all = true;
+ documents.clear();
+ return;
+ } else {
+ if("compteGestion".equals(item)) {
+ documents.add("compteGestion");
+ documents.add("cg-colloc");
+ } else if("documentPaye".equals(item)) {
+ documents.add("documentPaye");
+ documents.add("cfg-paye");
+ } else if("compteGestionEtat".equals(item)) {
+ documents.add("compteGestionEtat");
+ documents.add("cg-etat");
+ } else if("DocumentRapport".equals(item)) {
+ documents.add("DocumentRapport");
+ documents.add("rapport");
+ } else if("PES_Aller".equals(item)) {
+ documents.add("PES_Aller");
+ documents.add("pes-aller");
+ } else {
+ documents.add(item);
+ }
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2011 axYus - www.axyus.com
+ * 2011 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of Gestion-Droits.
+ *
+ * Gestion-Droits is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Gestion-Droits is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Gestion-Droits; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package fr.ccomptes.xemelios.credentials;
+
+/**
+ * Exception thrown if input line format is incorrect
+ * @author cmarchand
+ */
+public class ParsingException extends Exception {
+
+ public ParsingException() {
+ super();
+ }
+ public ParsingException(String message) { super(message); }
+ public ParsingException(String message, Throwable cause) { super(message, cause); }
+ public ParsingException(Throwable cause) { super(cause); }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Bosquet - charles.bosquet@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch;
+
+import fr.gouv.finances.dgfip.utils.DateUtils;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import java.io.File;
+import java.io.FileInputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+import org.apache.log4j.Logger;
+
+/**
+ * @author CBO
+ */
+public abstract class AbstractBatch {
+
+ static private final int SUCCESS_RETURN_CODE = 0;
+ static private final int ERROR_RETURN_CODE = 1;
+ private String args[];
+ private Logger logger;
+ private Date startDate;
+// private String batchVersion;
+ private SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
+
+ abstract protected void process() throws Exception;
+
+ public AbstractBatch(String args[]) {
+ this.args = args;
+ }
+
+ protected boolean canStart() throws Exception {
+ return true;
+ }
+
+ protected void processTerminaison() throws Exception {
+ }
+
+ public String[] getArgs() {
+ return args;
+ }
+
+ public int launchBatch() {
+ int codeRetour = ERROR_RETURN_CODE;
+ try {
+// // On initialise dans un premier temps les logs :
+// File log4jConfiFile = getConfFile("log4j.conf.file", "log4j.xml");
+// if (log4jConfiFile == null) {
+// throw new Exception("Fichier de configuration de log4j introuvable");
+// }
+// DOMConfigurator.configure(log4jConfiFile.toString());
+ this.logger = Logger.getLogger(this.getClass());
+ // On initialise le reste :
+ initialize();
+ if (canStart()) {
+ try {
+ this.startDate = new Date();
+// getLogger().info("Début du traitement de " + getShortName() + " " + getBatchVersion() + " le " + DateUtils.formatDateTime(startDate));
+// getLogger().info("Max memory : " + (Runtime.getRuntime().maxMemory() / 1024 / 1024) + " Mb");
+// getLogger().info("Total free memory : " + ((Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory() + Runtime.getRuntime().freeMemory()) / 1024 / 1024) + " Mb");
+ process();
+ Date endDate = new Date();
+ long duration = endDate.getTime() - startDate.getTime();
+// getLogger().info("Fin du traitement de " + getShortName() + " " + getBatchVersion() + " le " + DateUtils.formatDateTime(endDate) + " , durée : " + DateUtils.durationToString(duration));
+ } finally {
+ processTerminaison();
+ }
+ }
+ codeRetour = SUCCESS_RETURN_CODE;
+ } catch (Throwable throwable) {
+ String errorMessage = throwable.getMessage() != null ? throwable.getMessage() : throwable.toString();
+ if (this.logger != null) {
+ getLogger().error(errorMessage, throwable);
+ }
+ System.err.println("ERROR : " + DateUtils.formatDateTime(new Date()) + " : " + errorMessage);
+ throwable.printStackTrace();
+ }
+ return codeRetour;
+ }
+
+ protected void initialize() throws Exception {
+ File poolConfigFile = getConfFile("pool.conf.file", "mysql.properties");
+ if (poolConfigFile == null) {
+ throw new Exception("Fichier de configuration d'accès à la base de données non paramétré");
+ }
+ if (!poolConfigFile.exists()) {
+ throw new Exception("Fichier de configuration d'accès à la base de données introuvabel: " + poolConfigFile.getAbsolutePath());
+ }
+ Properties props = new Properties();
+ props.load(new FileInputStream(poolConfigFile));
+ PoolManager.getInstance().init(props);
+ Properties pomProperties = new Properties();
+// this.batchVersion = "unknown";
+ }
+
+ protected Logger getLogger() {
+ if (logger == null) {
+ throw new RuntimeException("Logger is not yet initialized");
+ }
+ return this.logger;
+ }
+
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ protected String getShortName() {
+ return getClass().getName().substring(getClass().getName().lastIndexOf(".") + 1);
+ }
+
+ protected abstract String getBatchVersion();
+
+ protected File getConfFile(String fileNameSystemProperty, String fileNameIfSystemPropertyNotFound) {
+ return getConfFile(fileNameSystemProperty, fileNameIfSystemPropertyNotFound, fileNameIfSystemPropertyNotFound);
+ }
+
+ protected File getConfFile(String fileNameSystemProperty, String fileNameIfSystemPropertyNotFound, String errorDisplayName) {
+ String confFileName = System.getProperty(fileNameSystemProperty);
+ File confFile = null;
+ if (confFileName == null) {
+ confFileName = "conf" + File.separator + fileNameIfSystemPropertyNotFound;
+ confFile = new File(confFileName);
+ if (!confFile.exists()) {
+ confFileName = fileNameIfSystemPropertyNotFound;
+ confFile = new File(confFileName);
+ if (!confFile.exists()) {
+ return null;
+ }
+ }
+ } else {
+ confFile = new File(confFileName);
+ if (!confFile.exists()) {
+ return null;
+ }
+ }
+ return confFile;
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Bosquet - charles.bosquet@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch;
+
+import fr.gouv.finances.cp.utils.PropertiesExpansion;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Properties;
+import org.apache.log4j.Logger;
+
+/**
+ * Classe regroupant les elements communs aux traitements batch
+ * @author CBO
+ */
+public abstract class Batch extends AbstractBatch {
+ private Properties props;
+ private List<String> postProcessors;
+ private boolean started = false;
+ private PropertiesExpansion applicationConfiguration;
+
+ /**
+ * @param args Arguments éventuels de la ligne de commande
+ */
+ public Batch(String args[]) {
+ super(args);
+ BatchRunner.getInstance().registerBatch(this);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ BatchRunner.getInstance().unregisterBatch(this);
+ super.finalize();
+ }
+
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ checkDirectories();
+ }
+
+ protected void checkDirectories() throws Exception { }
+
+ @Override
+ protected void processTerminaison() throws Exception {
+// Connection connection = null;
+// try {
+// connection = PoolManager.getInstance().getConnection();
+// } finally {
+// PoolManager.getInstance().releaseConnection(connection);
+// }
+ }
+
+ @Override
+ protected boolean canStart() throws Exception {
+ return true;
+ }
+
+
+ /**
+ * Implémentation du traitement
+ * @throws Exception
+ */
+ protected abstract void doProcess() throws Exception;
+
+ /**
+ * @return Resumé du traitement exemple: 35 fichiers traites avec succès, 3 dossiers en erreur
+ */
+ abstract public String getResumeTraitement();
+
+ /**
+ * @return Le refCode du type de traitement
+ */
+ abstract public String typeTraitementRefCode();
+
+ @Override
+ protected void process() throws Exception {
+ startRapportTraitements();
+ try {
+ started = true;
+ doProcess();
+ } catch (Throwable e) {
+ } finally {
+ endRapportTraitements();
+ }
+ }
+
+ public boolean isStarted() { return started; }
+
+ /**
+ * Démarre le rapport du traitement
+ */
+ private void startRapportTraitements() throws SQLException { }
+
+ /**
+ * Met fin au rapport traitememt
+ */
+ private void endRapportTraitements() throws SQLException { }
+
+ public Properties getProps() {
+ return props;
+ }
+
+ public void setProps(Properties props) {
+ this.props = props;
+ }
+
+ public List<String> getPostProcessors() {
+ return postProcessors;
+ }
+
+ public void setPostProcessors(List<String> postProcessors) {
+ this.postProcessors = postProcessors;
+ }
+
+ public abstract String getInformations();
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj instanceof Batch)
+ return hashCode()==obj.hashCode();
+ else
+ return obj.equals(this);
+ }
+
+
+ public abstract class RunnableBatch extends Thread {
+ private ThreadPool notifier = null;
+ public void setNotifier(ThreadPool th) {
+ this.notifier=th;
+ }
+ public ThreadPool getNotifier() { return notifier; }
+ public abstract String getInformations();
+ }
+ public static class ThreadPool<T extends RunnableBatch> {
+ private static final Logger logger = Logger.getLogger(ThreadPool.class);
+ private List<T> threads;
+ private int maxConcurrentThreads;
+ private int runningThreads = 0;
+ public ThreadPool(List<T> threads) {
+ super();
+ this.threads=threads;
+ }
+ public synchronized void notifyThreadStop(T thread) {
+ threads.remove(thread);
+ runningThreads--;
+ synchronized(this) {
+ for(RunnableBatch aThread:threads) {
+ if(runningThreads==maxConcurrentThreads) break;
+ if(!aThread.isAlive()) {
+ aThread.setNotifier(this);
+ runningThreads++;
+ aThread.start();
+ }
+ }
+ }
+ }
+ public void start(int maxConcurrentThreads) {
+ logger.debug("starting with "+maxConcurrentThreads+" max threads");
+ this.maxConcurrentThreads=maxConcurrentThreads;
+ while(runningThreads<maxConcurrentThreads && threads.size()>0) {
+ for(int i=0;i<threads.size();i++) {
+ if(!threads.get(i).isAlive()) {
+ threads.get(i).setNotifier(this);
+ runningThreads++;
+ threads.get(i).start();
+ break;
+ }
+ }
+ }
+ }
+ public int getRunningThreadCount() { return runningThreads; }
+ public List<T> getThreads() { return threads; }
+ }
+
+ public PropertiesExpansion getApplicationConfiguration() {
+ return applicationConfiguration;
+ }
+
+ public void setApplicationConfiguration(PropertiesExpansion applciationConfiguration) {
+ this.applicationConfiguration = applciationConfiguration;
+ }
+
+}
--- /dev/null
+/*
+ *
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 Christophe Marchand <christophe.marchand@axyus.com>
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+package fr.gouv.finances.dgfip.xemelios.batch;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.StringTokenizer;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public class BatchInformationListener {
+
+ private boolean stop = false;
+ private BatchRunner runner;
+ private ServerSocket server_socket = null;
+ private static BatchInformationListener instance = null;
+ private int port;
+
+ public BatchInformationListener(BatchRunner runner, int port) {
+ super();
+ BatchInformationListener.instance=this;
+ this.runner = runner;
+ this.port = port;
+ Thread starter = new Thread() {
+ public void run() {
+ try {
+ server_socket = new ServerSocket(BatchInformationListener.this.port);
+ while (!stop) {
+ Socket socket = server_socket.accept();
+
+ // Construct handler to process the HTTP request message.
+ try {
+ httpRequestHandler request = new httpRequestHandler(socket, BatchInformationListener.this.runner);
+ Thread thread = new Thread(request);
+
+ // Start the thread.
+ thread.start();
+ } catch (Exception e) {
+ }
+ }
+ } catch (IOException e) {
+ } finally {
+ try {
+ server_socket.close();
+ } catch (Throwable t) {
+ }
+ }
+ }
+ };
+ starter.start();
+ }
+
+ public void stop() {
+ stop = true;
+ try {
+ server_socket.close();
+ } catch (IOException ioEx) {
+ // on ignore
+ }
+
+ }
+ public static BatchInformationListener getInstance() { return instance; }
+}
+
+class httpRequestHandler implements Runnable {
+
+ final static String CRLF = "\r\n";
+ Socket socket;
+ OutputStream output;
+ BufferedReader br;
+ private BatchRunner runner;
+
+ // Constructor
+ public httpRequestHandler(Socket socket, BatchRunner runner) throws Exception {
+ this.socket = socket;
+ this.runner = runner;
+ this.output = socket.getOutputStream();
+ this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ }
+
+ // Implement the run() method of the Runnable interface.
+ public void run() {
+ try {
+ processRequest();
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+
+ private void processRequest() throws Exception {
+ String headerLine = br.readLine();
+ if (CRLF.equals(headerLine) || "".equals(headerLine)) {
+ return;
+ }
+
+ StringTokenizer s = new StringTokenizer(headerLine);
+ String temp = s.nextToken();
+
+ if (temp.equals("GET")) {
+ String path = s.nextToken();
+ String serverLine = "XeMeLios batch information serveur";
+ String statusLine = null;
+ String contentTypeLine = null;
+ String entityBody = null;
+ String contentLengthLine = "error";
+ String informations = null;
+ if("/".equals(path)) {
+ if (runner != null) {
+ statusLine = "HTTP/1.0 200 OK" + CRLF;
+ contentTypeLine = "Content-type: text/plain" + CRLF;
+ informations = runner.getInformations();
+ contentLengthLine = "Content-Length: " + Integer.toString(informations.length()) + CRLF;
+ } else {
+ statusLine = "HTTP/1.0 404 Not Found" + CRLF;
+ contentTypeLine = "text/html";
+ entityBody = "<HTML>" +
+ "<HEAD><TITLE>404 Not Found</TITLE></HEAD>" +
+ "<BODY>404 Not Found" + "<br>usage: http://server:" + socket.getPort() + "/</BODY></HTML>";
+ }
+ } else {
+ statusLine = "HTTP/1.0 404 Not Found" + CRLF;
+ contentTypeLine = "text/html";
+ entityBody = "<HTML>" +
+ "<HEAD><TITLE>404 Not Found</TITLE></HEAD>" +
+ "<BODY>404 Not Found" + "<br>usage: http://server:" + socket.getPort() + "/</BODY></HTML>";
+ }
+
+ output.write(statusLine.getBytes());
+ output.write(serverLine.getBytes());
+ // Send the content type line.
+ output.write(contentTypeLine.getBytes());
+ // Send the Content-Length
+ output.write(contentLengthLine.getBytes());
+ // Send a blank line to indicate the end of the header lines.
+ output.write(CRLF.getBytes());
+
+ // Send the entity body.
+ if (runner != null) {
+ output.write(informations.getBytes());
+ } else {
+ output.write(entityBody.getBytes());
+ }
+ }
+
+ try {
+ output.flush();
+ output.close();
+ br.close();
+ socket.close();
+ } catch (Exception e) {
+ }
+ }
+
+ private static String contentType(String fileName) {
+ if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
+ return "text/html";
+ } else if (fileName.endsWith(".zip")) {
+ return "multipart/x-zip";
+ }
+
+ return "";
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch;
+
+import fr.gouv.finances.cp.utils.PropertiesExpansion;
+import fr.gouv.finances.dgfip.utils.xml.FactoryProvider;
+import fr.gouv.finances.dgfip.xemelios.common.Constants;
+import fr.gouv.finances.dgfip.xemelios.common.config.DocumentsModel;
+import fr.gouv.finances.dgfip.xemelios.common.config.Loader;
+import fr.gouv.finances.dgfip.xemelios.data.DataConfigurationException;
+import fr.gouv.finances.dgfip.xemelios.data.DataLayerManager;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.net.Socket;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Timer;
+import java.util.TimerTask;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+import org.apache.log4j.Logger;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * This class plans batches, according to configuration file
+ * @author chm
+ */
+public class BatchRunner {
+ private static final Logger logger = Logger.getLogger(BatchRunner.class);
+ public static final String DATE_FORMAT="HH:mm";
+ private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+ private static final SimpleDateFormat debugSdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
+
+ public static final int DEFAULT_STOP_PORT = 8006;
+ public static final int DEFAULT_INFO_PORT = 8007;
+ private File configFile;
+ private ArrayList<MyTimer> timers;
+
+ private static BatchRunner instance;
+ private ArrayList<Batch> runningBatches;
+ private BatchInformationListener infoListener = null;
+ private boolean cancelled = false;
+
+ private DocumentsModel documents;
+
+ private PropertiesExpansion applicationConfiguration;
+
+ /**
+ * Point d'entrée
+ * Cette classe est lancée avec l'environnement définit en propriétés système.
+ * On les récupères pour faire un <code>applicationConfiguration</code> et le
+ * transmettre au besoin.
+ * @param args
+ */
+ public static void main(String args[]) {
+ if (args.length == 0) {
+ displaySyntax();
+ throw new RuntimeException("invalid syntax");
+ }
+ File configFileName = new File(args[0]);
+ if (!configFileName.exists()) {
+ displaySyntax();
+ throw new RuntimeException("config file not found: " + configFileName.getAbsolutePath());
+ }
+ if (args.length == 2 && "-stop".equals(args[1])) {
+ new BatchRunner(configFileName, true);
+ } else {
+ new BatchRunner(configFileName);
+ }
+ }
+
+ public BatchRunner(File configFile) {
+ super();
+ applicationConfiguration = restoreProperties();
+ if(instance==null) {
+ instance = this;
+ runningBatches = new ArrayList<Batch>();
+ }
+ this.configFile = configFile;
+ try {
+ preInit();
+ } catch(Throwable t) {
+ t.printStackTrace();
+ return;
+ }
+ try {
+ initialize();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ private static PropertiesExpansion restoreProperties() {
+ PropertiesExpansion applicationConfiguration = new PropertiesExpansion(System.getProperties());
+ return applicationConfiguration;
+ }
+
+ public BatchRunner(File configFile, boolean stop) {
+ super();
+ applicationConfiguration = restoreProperties();
+ if(instance==null) {
+ instance = this;
+ runningBatches = new ArrayList<Batch>();
+ }
+ this.configFile = configFile;
+ try {
+ preInit();
+ } catch(Throwable t) {
+ return;
+ }
+ if (!stop) {
+ try {
+ initialize();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ } else {
+ try {
+ DocumentBuilderFactory domFactory = FactoryProvider.getDocumentBuilderFactory();
+ domFactory.setNamespaceAware(true);
+ DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
+ Document config = domBuilder.parse(configFile);
+ XPathFactory xpf = XPathFactory.newInstance();
+ XPath xp = xpf.newXPath();
+ XPath xp2 = xpf.newXPath();
+ String sStopPort = (String) xp.evaluate("/batches/@stop-listen-port", config, XPathConstants.STRING);
+ int stopPort = DEFAULT_STOP_PORT;
+ try {
+ stopPort = Integer.parseInt(sStopPort);
+ } catch (NumberFormatException nfEx) {
+ throw new Exception("config file contains an invalid stop-port number");
+ }
+ stop(stopPort);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void initialize() throws Exception {
+ DocumentBuilderFactory domFactory = FactoryProvider.getDocumentBuilderFactory();
+ domFactory.setNamespaceAware(true);
+ DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
+ Document config = domBuilder.parse(configFile);
+ XPathFactory xpf = FactoryProvider.getXPathFactory();
+ XPath xp = xpf.newXPath();
+ XPath xp2 = xpf.newXPath();
+ timers = new ArrayList<MyTimer>();
+ String sStopPort = (String) xp.evaluate("/batches/@stop-listen-port", config, XPathConstants.STRING);
+ int stopPort = DEFAULT_STOP_PORT;
+ try {
+ stopPort = Integer.parseInt(sStopPort);
+ } catch (NumberFormatException nfEx) {
+ throw new Exception("config file contains an invalid stop-port number");
+ }
+ String allowedStoppers = (String) xp.evaluate("/batches/@allowedStoppers", config, XPathConstants.STRING);
+ try {
+ startStopListener(stopPort,allowedStoppers);
+ } catch(Exception ex) {
+ // si on a pas pu démarrer le listener, on quitte
+ for(Timer tm:timers) {
+ tm.cancel();
+ tm.purge();
+ }
+ return;
+ }
+ // on demarre le infoListener
+ String sInfoPort = (String) xp.evaluate("/batches/@info-listen-port", config, XPathConstants.STRING);
+ int infoPort = DEFAULT_INFO_PORT;
+ try {
+ infoPort = Integer.parseInt(sInfoPort);
+ } catch (NumberFormatException nfEx) {
+ Exception ex = new Exception("config file contains an invalid info-port number");
+ logger.error("while reading info-port number",ex);
+ }
+ try {
+ startInfoListener(infoPort);
+ } catch(Exception ex) {
+ // si on a pas pu démarrer le listener, on logge
+ logger.error("while starting info listener",ex);
+ }
+// on charge la configuration des documents
+ String docConfDir = xp.evaluate("/batches/parameter[@name='documents-def.dir']/text()", config);
+ initDocuments(docConfDir);
+ Object ret = xp.evaluate("/batches/batch[not(exists(@periodicity))]", config, XPathConstants.NODESET);
+ if (ret instanceof NodeList) {
+ NodeList nl = (NodeList)ret;
+ for( int i=0;i<nl.getLength(); i++) {
+ Element batch = (Element)nl.item(i);
+ String className = batch.getAttribute("class");
+ Properties props = new Properties();
+ NodeList parameters = (NodeList) xp2.evaluate("./parameter", batch, XPathConstants.NODESET);
+ for (int pCount=0; pCount<parameters.getLength(); pCount++) {
+ Element parameter = (Element)parameters.item(pCount);
+ String pName = parameter.getAttribute("name");
+ String pValue = null;
+ if (parameter.hasAttribute("value")) {
+ pValue = parameter.getAttribute("value");
+ } else {
+ pValue = parameter.getTextContent();
+ }
+ if (pName != null && pValue != null) {
+ props.setProperty(pName, pValue);
+ }
+ }
+ NodeList postProcessors = (NodeList) xp2.evaluate("./post-processor", batch, XPathConstants.NODESET);
+ ArrayList<String> postProcessorsClasses = new ArrayList<String>();
+ for(int ppCount = 0; ppCount < postProcessors.getLength(); ppCount++) {
+ Element pp = (Element)postProcessors.item(ppCount);
+ postProcessorsClasses.add(pp.getTextContent());
+ }
+ startNewBatch(className, /*periodicity, startTime,*/ props, postProcessorsClasses);
+ }
+// } else if (ret instanceof List) {
+// for (Element batch : (List<Element>) ret) {
+// }
+ }
+
+
+ ret = xp.evaluate("/batches/batch[@periodicity]", config, XPathConstants.NODESET);
+ if (ret instanceof NodeList) {
+ NodeList nl = (NodeList)ret;
+ for (int i=0; i<nl.getLength(); i++) {
+ Element batch = (Element)nl.item(i);
+ String className = batch.getAttribute("class");
+ String periodicity = batch.getAttribute("periodicity");
+ String startTime = batch.getAttribute("start-time");
+ Properties props = new Properties();
+ NodeList parameters = (NodeList) xp2.evaluate("./parameter", batch, XPathConstants.NODESET);
+ for (int j=0;j<parameters.getLength();j++) {
+ Element parameter = (Element)parameters.item(j);
+ String pName = parameter.getAttribute("name");
+ String pValue = null;
+ if (parameter.hasAttribute("value")) {
+ pValue = parameter.getAttribute("value");
+ } else {
+ pValue = parameter.getTextContent();
+ }
+ if (pName != null && pValue != null) {
+ props.setProperty(pName, pValue);
+ }
+ }
+ NodeList postProcessors = (NodeList) xp2.evaluate("./post-processor", batch, XPathConstants.NODESET);
+ ArrayList<String> postProcessorsClasses = new ArrayList<String>();
+ for(int k=0;k<postProcessors.getLength();k++) {
+ Element el = (Element)postProcessors.item(k);
+ postProcessorsClasses.add(el.getTextContent());
+ }
+ startNewBatch(className, periodicity, startTime, props, postProcessorsClasses);
+ }
+// } else if (ret instanceof List) {
+ }
+
+ }
+
+ protected void initDocuments(String dirs) {
+ try {
+ File baseDir = BatchRunner.getBaseDir();
+ String canon = baseDir.getCanonicalPath().replace("\\", "/");
+ String documentsDefDirs = dirs.replaceAll("%basedir%", canon);
+ documents = Loader.getDocumentsInfos(documentsDefDirs);
+ } catch(Exception ex) {
+ System.err.println("Failed to load documents configuration from "+dirs);
+ ex.printStackTrace();
+ }
+ }
+
+ protected void startNewBatch(String className, String periodicity, String startTime, Properties props, ArrayList<String> postProcessors) {
+ if(cancelled) return;
+ try {
+ Class clazz = Class.forName(className);
+ TimerBatchTask task = new TimerBatchTask(clazz, props, postProcessors);
+ char unity = periodicity.charAt(periodicity.length() - 1);
+ int qty = Integer.parseInt(periodicity.substring(0, periodicity.length() - 1));
+ long period = 0;
+ switch (unity) {
+ case 's': {
+ period = qty * 1000;
+ break;
+ }
+ case 'm': {
+ period = qty * 1000 * 60;
+ break;
+ }
+ case 'h': {
+ period = qty * 1000 * 60 * 60;
+ break;
+ }
+ case 'd': {
+ period = qty * 1000 * 60 * 60 * 24;
+ break;
+ }
+ default:
+ throw new RuntimeException(periodicity + " is not a valid periodicity. Periodicity must be a quantity followed by 's', 'm', 'h' or 'd'");
+ }
+ if(startTime==null || startTime.length()==0) {
+ try {
+ MyTimer timer = new MyTimer(className);
+ timers.add(timer);
+ timer.scheduleAtFixedRate(task, 1000, period);
+ } catch(Exception ex) {
+ System.err.println("ERROR while starting "+task.batchClass.getName());
+ }
+ } else {
+ Date d = sdf.parse(startTime);
+ GregorianCalendar gc = new GregorianCalendar();
+ GregorianCalendar thisMorning = new GregorianCalendar(gc.get(Calendar.YEAR),gc.get(Calendar.MONTH),gc.get(Calendar.DAY_OF_MONTH));
+ Date start = new Date(thisMorning.getTimeInMillis()+d.getTime()+thisMorning.getTimeZone().getDSTSavings());
+ MyTimer timer = new MyTimer(className);
+ timers.add(timer);
+ timer.scheduleAtFixedRate(task, start, period);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex);
+ }
+ }
+ protected void startNewBatch(String className, Properties props, ArrayList<String> postProcessors) {
+ if(cancelled) return;
+ try {
+ Class clazz = Class.forName(className);
+ Constructor<Batch> cstr = clazz.getConstructor(String[].class);
+ Batch batch = cstr.newInstance(new Object[]{new String[]{}});
+ batch.setProps(props);
+ batch.setPostProcessors(postProcessors);
+ batch.launchBatch();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static void displaySyntax() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("java ").append(BatchRunner.class.getName()).append(" <config-file> [-stop]\n\twhere <config-file> is the fully-qualified location of config file.");
+ System.err.println(sb.toString());
+ }
+
+ public void stop(int port) throws Exception {
+ logger.info("Stopping batch server");
+ Socket so = new Socket("localhost", port);
+ BufferedReader br = new BufferedReader(new InputStreamReader(so.getInputStream()));
+ PrintWriter pw = new PrintWriter(so.getOutputStream(), true);
+ String resp = br.readLine();
+ if (resp.startsWith("+OK")) {
+ pw.println("stop");
+ resp = br.readLine();
+ } else {
+ logger.error("batch server has respond : " +resp);
+ }
+ so.close();
+ }
+
+ protected void preInit() throws Exception {
+ // On initialise dans un premier temps les logs :
+ File log4jConfiFile = getConfFile("log4j.conf.file", "log4j.xml");
+ if (log4jConfiFile == null) {
+ throw new Exception("Fichier de configuration de log4j introuvable");
+ }
+ DOMConfigurator.configure(log4jConfiFile.toString());
+ initDataLayer();
+ logger.debug("datalayer initialized");
+ }
+ protected void initDataLayer() throws DataConfigurationException {
+ try {
+ DataLayerManager.getImplementation();
+ } catch(DataConfigurationException dcEx) {
+ String availableLayers = applicationConfiguration.getProperty(Constants.SYS_PROP_AVAILABLE_LAYERS);
+ if(availableLayers==null) availableLayers = "fr.gouv.finances.cp.xemelios.data.impl.MySqlDataLayer";
+ StringTokenizer tokenizer = new StringTokenizer(availableLayers, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String className = tokenizer.nextToken();
+ try {
+ Class.forName(className);
+ } catch (ClassNotFoundException cnfEx) {
+ logger.error("instanciating data layer: ", cnfEx);
+ }
+ }
+ DataLayerManager.setApplicationProperties(applicationConfiguration);
+ DataLayerManager.setDataImpl("mysql");
+ }
+ }
+
+ protected File getConfFile(String fileNameSystemProperty, String fileNameIfSystemPropertyNotFound) {
+ return getConfFile(fileNameSystemProperty, fileNameIfSystemPropertyNotFound, fileNameIfSystemPropertyNotFound);
+ }
+
+ protected File getConfFile(String fileNameSystemProperty, String fileNameIfSystemPropertyNotFound, String errorDisplayName) {
+ String confFileName = System.getProperty(fileNameSystemProperty);
+ File confFile = null;
+ if (confFileName == null) {
+ confFileName = "conf" + File.separator + fileNameIfSystemPropertyNotFound;
+ confFile = new File(confFileName);
+ if (!confFile.exists()) {
+ confFileName = fileNameIfSystemPropertyNotFound;
+ confFile = new File(confFileName);
+ if (!confFile.exists()) {
+ return null;
+ }
+ }
+ } else {
+ confFile = new File(confFileName);
+ if (!confFile.exists()) {
+ return null;
+ }
+ }
+ return confFile;
+ }
+
+ protected void startInfoListener(int port) throws Exception {
+ infoListener = new BatchInformationListener(this,port);
+ }
+
+ protected void startStopListener(int port, String allowedStoppers) throws Exception {
+ StopServer stopServer = new StopServer(port, timers, allowedStoppers);
+ try {
+ stopServer.start();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("an other instance is already running.");
+ }
+ }
+
+ public static File getBaseDir() {
+ String runDir = System.getProperty("user.dir");
+ File f = new File(runDir);
+ // dans le cas d'un deploy batch
+ if(f.getName().equals("bin")) return f.getParentFile();
+ // dans le cas d'execution dans IDE
+ else return f;
+ }
+
+ public static BatchRunner getInstance() { return instance; }
+ public void registerBatch(Batch batch) {
+ logger.info("registring batch "+batch.typeTraitementRefCode());
+ runningBatches.add(batch);
+ }
+ public void unregisterBatch(Batch batch) {
+ runningBatches.remove(batch);
+ logger.info("unregistring batch "+batch.typeTraitementRefCode());
+ }
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ for(Batch batch:runningBatches) {
+ sb.append(batch.getInformations());
+ }
+ return sb.toString();
+ }
+ public class TimerBatchTask extends TimerTask {
+
+ private Class batchClass;
+ private Properties props;
+ private List<String> postProcessors;
+
+ public TimerBatchTask(Class clazz, Properties props, List<String> postProcessors) {
+ super();
+ this.batchClass = clazz;
+ this.props = props;
+ this.postProcessors=postProcessors;
+ }
+
+ @Override
+ public void run() {
+ try {
+ @SuppressWarnings("unchecked")
+ // TODO : vérifier que la précédente instance a finit
+ Constructor<Batch> cstr = batchClass.getConstructor(String[].class);
+ Batch batch = cstr.newInstance(new Object[]{new String[]{}});
+ batch.setApplicationConfiguration(applicationConfiguration);
+ batch.setProps(props);
+ batch.setPostProcessors(postProcessors);
+ batch.launchBatch();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+
+ public DocumentsModel getDocuments() {
+ return documents;
+ }
+
+}
--- /dev/null
+/*
+ *
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 Christophe Marchand <christophe.marchand@axyus.com>
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch;
+
+import java.util.Timer;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+class MyTimer extends Timer {
+ private boolean canceled = false;
+
+ public MyTimer() {
+ super();
+ }
+ public MyTimer(boolean isDeamon) {
+ super(isDeamon);
+ }
+ public MyTimer(String name) {
+ super(name);
+ }
+ public MyTimer(String name, boolean isDeamon) {
+ super(name,isDeamon);
+ }
+
+ @Override
+ public void cancel() {
+ canceled = true;
+ super.cancel();
+ }
+
+ public boolean isCanceled() { return canceled; }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch;
+
+import fr.gouv.finances.dgfip.xemelios.export.ExportJob;
+
+/**
+ * Defines the post-export process
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public interface PostProcessor {
+
+ /**
+ * Defines the export job to post-process
+ * @param job
+ */
+ public void setConfigData(Object data);
+ /**
+ * Run the post process
+ * @throws java.lang.Exception
+ */
+ public void postProcess() throws Exception;
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch;
+
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.Timer;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author chm
+ */
+public class StopServer {
+ private static final Logger logger = Logger.getLogger(StopServer.class);
+ private int port = 0;
+ private ArrayList<MyTimer> timers;
+ private ServerSocket ss;
+ private String[] allowedStoppers;
+ protected boolean listening = true;
+
+ /**
+ *
+ * @param port
+ * @param timers
+ * @param allowedStoppers
+ */
+ public StopServer(int port, final ArrayList<MyTimer> timers, String allowedStoppers) {
+ super();
+ this.port = port;
+ this.timers=timers;
+ StringTokenizer st = new StringTokenizer(allowedStoppers, ",");
+ this.allowedStoppers = new String[st.countTokens()];
+ for(int i=0;i<st.countTokens();i++) {
+ this.allowedStoppers[i] = st.nextToken();
+ }
+ }
+
+ public void start() throws Exception {
+ Thread starter = new Thread() {
+ @Override
+ public void run() {
+ try {
+ ss = new ServerSocket(port);
+ int count = 0;
+ while(listening) {
+ if(listening) {
+ ++count;
+ try {
+ new StopServerThread(ss.accept(),StopServer.this,allowedStoppers).start();
+ } catch(Exception ex) {
+ // throwed when ss has been closed
+ }
+ }
+ }
+ if(!ss.isClosed()) ss.close();
+ } catch(IOException ioEx) {
+ System.err.println("Another instance is already running.");
+ System.exit(2);
+ }
+ }
+ };
+ starter.start();
+ }
+ protected void stop() {
+ listening=false;
+ BatchInformationListener.getInstance().stop();
+ for(Timer timer:timers) {
+ timer.cancel();
+ timer.purge();
+ }
+ PoolManager.getInstance().shutdown();
+ System.exit(1);
+ }
+
+ private class StopServerThread extends Thread {
+ private Socket so;
+ private StopServer instance;
+ private String[] allowedStoppers;
+ public StopServerThread(Socket so, StopServer instance, String[] allowedStoppers) {
+ super();
+ this.so=so;
+ this.instance=instance;
+ this.allowedStoppers=allowedStoppers;
+ }
+ @Override
+ public void run() {
+ try {
+ PrintWriter out = new PrintWriter(so.getOutputStream(),true);
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(so.getInputStream()));
+
+ String inputLine, outputLine;
+ if(isAcceptedStopper(so.getInetAddress().getHostAddress())) {
+ logger.info("received stop order from "+so.getInetAddress().getHostAddress());
+ Protocol kkp = new Protocol();
+ outputLine = kkp.processInput(null);
+ out.println(outputLine);
+
+ while ((inputLine = in.readLine()) != null) {
+ outputLine = kkp.processInput(inputLine);
+ out.println(outputLine);
+ if (outputLine.startsWith("+OK Bye.")) {
+ instance.stop();
+ break;
+ }
+ }
+ } else {
+ out.println("-ERR Unauthorized stopper, allowed are: "+allowedStoppers+", found "+so.getInetAddress().getHostAddress());
+ }
+ out.close();
+ in.close();
+ so.close();
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ protected boolean isAcceptedStopper(String address) {
+ boolean ret = false;
+ for(String s:allowedStoppers) {
+ if("*".equals(s)) {
+ ret = true;
+ break;
+ } else if(address.equals(s)) {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+ }
+ }
+
+ private class Protocol {
+ private static final String WELCOME_STRING = "+OK Welcome on XeMeLios batch stopper";
+ public String processInput(String input) {
+ if(input==null) {
+ return WELCOME_STRING;
+ } else {
+ if("stop".equals(input)) {
+ return "+OK Bye.";
+ } else {
+ return "-ERR Unknown command.";
+ }
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ *
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 Christophe Marchand <christophe.marchand@axyus.com>
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.exports;
+
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import fr.gouv.finances.dgfip.xemelios.export.ExportJob;
+import fr.gouv.finances.dgfip.xemelios.utils.FileUtils;
+import java.io.File;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public class ExportCleaner extends Batch {
+ private static final Logger logger = Logger.getLogger(ExportCleaner.class);
+
+ public static final String PROP_MAX_CONCURRENT_THREADS = "max.concurrent.threads";
+ public static final String PROP_CLEAN_DELAY = "clean.delay";
+ private int maxConcurrentThreads = 1;
+ private int cleanDelay = 14;
+
+ private ThreadPool<ExportCleanerImpl> pool = null;
+
+ public ExportCleaner(String[] args) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ String sTmp = getProps().getProperty(PROP_MAX_CONCURRENT_THREADS);
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ maxConcurrentThreads = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ sTmp = getProps().getProperty(PROP_CLEAN_DELAY);
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ cleanDelay = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ StringBuffer sql = new StringBuffer("SELECT EXPORT_ID, UTI_LOGIN FROM EXPORT_JOBS WHERE STATUS IN (");
+ sql.append(ExportJob.STATUS_DOWNLOADED).append(",").append(ExportJob.STATUS_ERROR).append(",").append(ExportJob.STATUS_TERMINATED);
+ sql.append(") AND TO_DAYS(NOW()) - TO_DAYS(SUBMIT_DATE) > ").append(cleanDelay).append(" AND CLEANED IS NULL");
+ ResultSet rs = con.createStatement().executeQuery(sql.toString());
+ ArrayList<ExportCleanerImpl> threads = new ArrayList<ExportCleanerImpl>();
+ while(rs.next()) {
+ long exportId = rs.getLong(1);
+ String user = rs.getString(2);
+ threads.add(new ExportCleanerImpl(exportId,user));
+ }
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ pool = new ThreadPool<ExportCleanerImpl>(threads);
+ pool.start(maxConcurrentThreads);
+ } catch(Exception ex) {
+ logger.error("doProcess(): ",ex);
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "export.cleaner.resume";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "export.cleaner";
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+ sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+ for(RunnableBatch rb: pool.getThreads()) {
+ sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+ if(rb.isAlive()) sb.append(rb.getInformations());
+ }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+
+ protected class ExportCleanerImpl extends RunnableBatch {
+ private Long exportId;
+ private String user;
+
+ public ExportCleanerImpl(Long exportId, String user) {
+ super();
+ this.exportId=exportId;
+ this.user=user;
+ setName("ExportCleanerImpl<"+exportId+","+user+">");
+ }
+
+ @Override
+ public void run() {
+ logger.debug("cleaning export "+exportId+" from "+user);
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ PreparedStatement ps = con.prepareStatement("SELECT GENERATED_FILE_NAME FROM EXPORT_JOBS WHERE EXPORT_ID=? AND UTI_LOGIN=?");
+ ps.setLong(1,exportId);
+ ps.setString(2,user);
+ ResultSet rs= ps.executeQuery();
+ if(rs.next()) {
+ String generatedFileName = rs.getString(1);
+ if(rs.wasNull()) generatedFileName = null;
+ clean(generatedFileName);
+ ps = con.prepareStatement("UPDATE EXPORT_JOBS SET CLEANED=1 WHERE EXPORT_ID=? AND UTI_LOGIN=?");
+ ps.setLong(1,exportId);
+ ps.setString(2,user);
+ ps.executeUpdate();
+ } else {
+ logger.warn("export to clean not found !");
+ }
+ } catch(Exception ex) {
+ logger.error("ExportCleanerImpl.run(): ",ex);
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ }
+ getNotifier().notifyThreadStop(this);
+ }
+ }
+ protected void clean(String fileName) {
+ if(fileName==null) return;
+ File f = new File(fileName);
+ if(f.exists()) {
+ File dir = f.getParentFile();
+ try {
+ FileUtils.dropRecursiveDirectory(dir);
+ } catch(Exception ex) {}
+ }
+ }
+
+ @Override
+ public String getInformations() {
+ if(isAlive()) return "\t".concat(getName()).concat(": running\n");
+ else return "\t".concat(getName()).concat(": idle\n");
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ *
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 Christophe Marchand <christophe.marchand@axyus.com>
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.exports;
+
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public class ExportEvaluator extends Batch {
+ private static final Logger logger = Logger.getLogger(ExportEvaluator.class);
+ private static final int EXPORT_MAX_SIZE = 1000;
+ private static final int EXPORT_P1_MAX_SIZE = 10;
+ private static final int EXPORT_P2_MAX_SIZE = 100;
+ public static final int MAX_CONCURRENT_THREADS = 3;
+
+ public static final String PROP_EXP_MAX_SIZE = "export.max.size";
+ public static final String PROP_P1_MAX_SIZE = "export.p1.max.size";
+ public static final String PROP_P2_MAX_SIZE = "export.p2.max.size";
+ public static final String PROP_MAX_CONCURRENT_THREADS = "max.concurrent.threads";
+
+ private int maxConcurrentThreads = MAX_CONCURRENT_THREADS;
+ private int p1MaxSize = EXPORT_P1_MAX_SIZE;
+ private int p2MaxSize = EXPORT_P2_MAX_SIZE;
+ private int maxSize = EXPORT_MAX_SIZE;
+
+ private ThreadPool<ExportEvaluatorImpl> pool=null;
+
+ public ExportEvaluator(String args[]) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ try {
+ String s = getProps().getProperty(PROP_EXP_MAX_SIZE);
+ if(s!=null && s.length()>0) {
+ maxSize = Integer.parseInt(s);
+ }
+ } catch(Throwable t) {}
+ try {
+ String s = getProps().getProperty(PROP_P1_MAX_SIZE);
+ if(s!=null && s.length()>0) {
+ p1MaxSize = Integer.parseInt(s);
+ }
+ } catch(Throwable t) {}
+ try {
+ String s = getProps().getProperty(PROP_P2_MAX_SIZE);
+ if(s!=null && s.length()>0) {
+ p2MaxSize = Integer.parseInt(s);
+ }
+ } catch(Throwable t) {}
+ String sTmp = getProps().getProperty(PROP_MAX_CONCURRENT_THREADS);
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ maxConcurrentThreads = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ }
+
+
+
+ @Override
+ protected void doProcess() throws Exception {
+ Connection con = null;
+ Statement st = null;
+ ResultSet rs = null;
+ ArrayList<ExportEvaluatorImpl> threads = new ArrayList<ExportEvaluatorImpl>();
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sqlParam = "SELECT PARAM_VALUE FROM PARAMETERS WHERE PARAM_NAME='export.temp.directory'";
+ st = con.createStatement();
+ rs = st.executeQuery(sqlParam);
+ if(rs.next()) {
+ String exportTempDirectory = rs.getString(1);
+ rs.close();
+ } else {
+ logger.error("parameter 'export.temp.directory' not set !");
+ throw new Exception("parameter 'export.temp.directory' not set !");
+ }
+ String sql = "SELECT EXPORT_ID, UTI_LOGIN FROM EXPORT_JOBS WHERE STATUS=0";
+ rs = st.executeQuery(sql);
+ while(rs.next()) {
+ threads.add(new ExportEvaluatorImpl(rs.getLong(1),rs.getString(2),p1MaxSize,p2MaxSize,maxSize));
+ }
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ pool = new ThreadPool<ExportEvaluatorImpl>(threads);
+ pool.start(maxConcurrentThreads);
+ } catch(SQLException sqlEx) {
+ // TODO
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "export.evaluator.resume";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "export.evaluator";
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+ sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+ for(RunnableBatch rb: pool.getThreads()) {
+ sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+ if(rb.isAlive()) sb.append(rb.getInformations());
+ }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+ protected class ExportEvaluatorImpl extends RunnableBatch {
+ private final Logger logger = Logger.getLogger(ExportEvaluatorImpl.class);
+ private Long exportId;
+ private String user;
+ private int p1MaxSize, p2MaxSize, maxSize;
+ public ExportEvaluatorImpl(Long exportId,String user, int p1MaxSize, int p2MaxSize, int maxSize) {
+ this.exportId=exportId;
+ this.user=user;
+ this.p1MaxSize=p1MaxSize;
+ this.p2MaxSize=p2MaxSize;
+ this.maxSize=maxSize;
+ setName("ExportEvaluatorImpl<"+exportId+">");
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void run() {
+ Connection con = null;
+ try {
+ int priority = -1;
+ String errorMessage=null;
+ con = PoolManager.getInstance().getConnection();
+ PreparedStatement ps = con.prepareStatement("SELECT SIZE FROM EXPORT_JOBS WHERE EXPORT_ID=? AND UTI_LOGIN=?");
+ ps.setLong(1,exportId);
+ ps.setString(2,user);
+ ResultSet rs = ps.executeQuery();
+ if(rs.next()) {
+ int size = rs.getInt(1);
+ if(size<p1MaxSize) priority = 1;
+ else if(size<p2MaxSize) priority = 2;
+ else if(size<maxSize) priority = 3;
+ else errorMessage="Il y a trop de données à exporter pour réaliser cet export ; les seuils sont "+p1MaxSize+","+p2MaxSize+","+maxSize+".";
+ } else {
+ errorMessage = "Erreur inattendue";
+ }
+ if(priority>0) {
+ ps = con.prepareStatement("UPDATE EXPORT_JOBS SET PRIORITY=?, STATUS=1 WHERE EXPORT_ID=? AND UTI_LOGIN=?");
+ ps.setInt(1,priority);
+ ps.setLong(2,exportId);
+ ps.setString(3,user);
+ ps.executeUpdate();
+ } else {
+ ps = con.prepareStatement("UPDATE EXPORT_JOBS SET ERROR_MESSAGE=? ,STATUS=5 WHERE EXPORT_ID=?");
+ ps.setString(1,errorMessage);
+ ps.setLong(2, exportId);
+ ps.executeUpdate();
+ }
+ } catch(SQLException sqlEx) {
+ logger.error("run<"+exportId+">()", sqlEx);
+ }catch(Throwable t) {
+ logger.error("run<"+exportId+">()", t);
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ getNotifier().notifyThreadStop(this);
+ }
+ }
+
+ @Override
+ public String getInformations() {
+ return "\tevaluating export :".concat(Long.toString(exportId)).concat("\n");
+ }
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2010 axYus - http://www.axyus.com
+ * 2010 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS_NB.
+ *
+ * XEMELIOS_NB is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS_NB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS_NB; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.exports;
+
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+import org.apache.log4j.Logger;
+
+/**
+ * Initialise les exports qui étaient en cours lors de l'arrêt des batchs
+ * @author cmarchand
+ */
+public class ExportInitiator extends Batch {
+ private static final Logger logger = Logger.getLogger(ExportInitiator.class);
+
+ public ExportInitiator(String args[]) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ logger.info("Running ExportInitiator");
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ PreparedStatement ps = con.prepareStatement("UPDATE EXPORT_JOBS SET STATUS=1, RUN_DATE=? WHERE STATUS=2");
+ ps.setNull(1, Types.DATE);
+ ps.executeUpdate();
+ } catch(Exception ex) {
+ logger.error(ex);
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return null;
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "Export initiator";
+ }
+
+ @Override
+ public String getInformations() {
+ return null;
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1";
+ }
+
+
+
+}
--- /dev/null
+/*
+ *
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 Christophe Marchand <christophe.marchand@axyus.com>
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.exports;
+
+import fr.gouv.finances.dgfip.xemelios.batch.PostProcessor;
+import fr.gouv.finances.cp.xemelios.export.ExportUndertaker;
+import fr.gouv.finances.cp.xemelios.export.Exporter;
+import fr.gouv.finances.dgfip.xemelios.auth.XemeliosUser;
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.batch.BatchRunner;
+import fr.gouv.finances.dgfip.xemelios.common.config.DocumentModel;
+import fr.gouv.finances.dgfip.xemelios.common.config.DocumentsModel;
+import fr.gouv.finances.dgfip.xemelios.common.config.ElementModel;
+import fr.gouv.finances.dgfip.xemelios.data.DataLayerManager;
+import fr.gouv.finances.dgfip.xemelios.data.DataResultSet;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import fr.gouv.finances.dgfip.xemelios.export.ConfigModel;
+import fr.gouv.finances.dgfip.xemelios.export.ExportJob;
+import fr.gouv.finances.dgfip.xemelios.utils.FileUtils;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public class ExportRunner extends Batch {
+ private static final Logger logger = Logger.getLogger(ExportRunner.class);
+
+ public static final String PROP_PRIORITY_LEVEL = "priority.level";
+ public static final String PROP_MAX_CONCURRENT_THREADS = "max.concurrent.threads";
+ public static final String PROP_DOCUMENTS_DEF_DIR = "documents-def.dir";
+// public static final String PROP_DATALAYER_NAME = "datalayer.name";
+ public static final String PROP_UNDERTAKER = "exporter.class.name";
+
+ private int priorityLevel = 1;
+ private int maxConcurrentThreads = 1;
+
+ private String exportTempDirectory = null;
+ private String undertakerClassName;
+
+ private static boolean initialized = false;
+
+ private ThreadPool<ExportRunnerImpl> pool = null;
+
+ public ExportRunner(String args[]) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ String sTmp = getProps().getProperty(PROP_MAX_CONCURRENT_THREADS);
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ maxConcurrentThreads = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ try {
+ String s = getProps().getProperty(PROP_PRIORITY_LEVEL);
+ if(s!=null && s.length()>0) {
+ priorityLevel = Integer.parseInt(s);
+ }
+ } catch(Throwable t) {}
+ undertakerClassName = getProps().getProperty(PROP_UNDERTAKER);
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ logger.debug("running export.runner for priority "+priorityLevel);
+ Connection con = null;
+ Statement st = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ ArrayList<ExportRunnerImpl> threads = new ArrayList<ExportRunnerImpl>();
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sqlParam = "SELECT PARAM_VALUE FROM PARAMETERS WHERE PARAM_NAME='export.temp.directory'";
+ st = con.createStatement();
+ rs = st.executeQuery(sqlParam);
+ if(rs.next()) {
+ exportTempDirectory = rs.getString(1);
+ rs.close();
+ } else {
+ logger.error("parameter 'export.temp.directory' not set !");
+ throw new Exception("parameter 'export.temp.directory' not set !");
+ }
+ String sql = "SELECT EXPORT_ID, UTI_LOGIN FROM EXPORT_JOBS WHERE STATUS=1 AND PRIORITY=? AND CLEANED IS NULL";
+ ps = con.prepareStatement(sql);
+ ps.setInt(1,priorityLevel);
+ rs = ps.executeQuery();
+ while(rs.next()) {
+ Long exportId = rs.getLong(1);
+ String user = rs.getString(2);
+ logger.debug("planning ("+exportId+","+user+") for priority "+priorityLevel+" - threads.size="+threads.size());
+ ExportRunnerImpl impl = new ExportRunnerImpl(exportId, user,priorityLevel,exportTempDirectory,BatchRunner.getInstance().getDocuments(),undertakerClassName,getPostProcessors());
+ logger.debug("ExportRunnerImpl created");
+ threads.add(impl);
+ logger.debug("thread "+exportId+","+user+"added, size is now "+threads.size());
+ }
+ logger.debug("creating pool for priority "+priorityLevel);
+ pool = new ThreadPool<ExportRunnerImpl>(threads);
+ logger.debug("starting pool for priority "+priorityLevel+" with "+maxConcurrentThreads+" max concurrent threads");
+ pool.start(maxConcurrentThreads);
+ } catch(SQLException sqlEx) {
+ logger.error("doProcess()",sqlEx);
+ } catch(Throwable t) {
+ t.printStackTrace();
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "export.runner.resume";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "export.runner<"+priorityLevel+">";
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+ sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+ for(RunnableBatch rb: pool.getThreads()) {
+ sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+ if(rb.isAlive()) sb.append(rb.getInformations());
+ }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+ protected class ExportRunnerImpl extends RunnableBatch {
+ private Long exportId;
+ private String user;
+ private int priority;
+ private String exportDirectory;
+ private DocumentsModel docs;
+ private String undertakerClassName;
+ private List<String> postProcessors;
+
+ private ExportJob job = null;
+
+ private File generatedFile;
+
+ private PostProcessor pp;
+
+ private boolean exportTerminated = false;
+
+ public ExportRunnerImpl(Long exportId, String user, int priority, String exportDirectory, DocumentsModel docs, String undertakerClassName,List<String> postProcessors) {
+ super();
+ logger.debug("ExportRunnerImpl<init>("+exportId+","+user+")");
+ this.exportId=exportId;
+ this.user=user;
+ this.priority=priority;
+ this.exportDirectory=exportDirectory;
+ this.docs=docs;
+ this.undertakerClassName=undertakerClassName;
+ this.postProcessors=postProcessors;
+ setName("ExportRunnerImpl<"+exportId+","+user+">");
+
+ switch(priority) {
+ case 2: { setPriority(Thread.MIN_PRIORITY); break; }
+ default: { setPriority(Thread.NORM_PRIORITY); break; }
+ }
+ }
+
+ @Override
+ public void run() {
+ logger.debug("running ExportRunnerImpl for "+user+"/"+exportId);
+ Connection con = null;
+ File temp = null;
+ try {
+ job = DataLayerManager.getImplementation().getExportJob(exportId,user);
+ con = PoolManager.getInstance().getConnection();
+ String sql = "UPDATE EXPORT_JOBS SET STATUS="+ExportJob.STATUS_RUNNING+", RUN_DATE=NOW() WHERE EXPORT_ID=? AND UTI_LOGIN=?";
+ PreparedStatement ps = con.prepareStatement(sql);
+ ps.setLong(1, exportId);
+ ps.setString(2,user);
+ ps.executeUpdate();
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ DataResultSet drs = job.getDataResultSet();
+ File dir = new File(exportDirectory);
+ temp = File.createTempFile("exp-", null, dir);
+ temp.delete();
+ temp.mkdir();
+ String fileName = null;
+ if(job.getFileName().toLowerCase().endsWith(".xls")) fileName = job.getFileName();
+ else fileName = job.getFileName().concat(".xls");
+ generatedFile = new File(temp,fileName);
+ DocumentModel dm = docs.getDocumentById(job.getDocumentId());
+ User user2 = new User(user); // job.getOwner()
+logger.debug("getting ConfigModel");
+ ConfigModel cm = DataLayerManager.getImplementation().getConfigExport(job.getDocumentId(), job.getEtatId(), job.getExportConfigId().toString(), user2);
+logger.debug("creating MyExporter");
+ MyExporter exporter = new MyExporter(generatedFile, drs, dm, job.getEtatId(), dm.getEtatById(job.getEtatId()).getElementById(job.getElementId()), cm, this, undertakerClassName);
+logger.debug("running myExporter");
+ exporter.runImmediatly();
+ } catch(Exception ex) {
+ logger.error("run()",ex);
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sql = "UPDATE EXPORT_JOBS SET STATUS="+ExportJob.STATUS_ERROR+", ERROR_MESSAGE=? WHERE EXPORT_ID=? AND UTI_LOGIN=?";
+ PreparedStatement ps = con.prepareStatement(sql);
+ ps.setString(1,ex.getMessage());
+ ps.setLong(2, exportId);
+ ps.setString(3, user);
+ ps.executeUpdate();
+ } catch(SQLException sqlEx) {}
+ if(temp!=null) {
+ if(temp.exists()) {
+ if(temp.isDirectory()) {
+ try {
+ FileUtils.dropRecursiveDirectory(temp);
+ } catch(Exception ex2) {}
+ } else {
+ temp.delete();
+ }
+ }
+ }
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ // c'est fait par le MyExporter
+ // getNotifier().notifyThreadStop(this);
+ }
+ }
+ @SuppressWarnings("unchecked")
+ public void notifyTerminated() {
+ exportTerminated = true;
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ PreparedStatement ps = con.prepareStatement("UPDATE EXPORT_JOBS SET GENERATED_FILE_NAME=? WHERE EXPORT_ID=? AND UTI_LOGIN=?");
+ ps.setString(1, generatedFile.getAbsolutePath());
+ ps.setLong(2, exportId);
+ ps.setString(3,user);
+ ps.executeUpdate();
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ job.setGeneratedFileName(generatedFile.getAbsolutePath());
+
+ // post processors
+ for(String postProcessor:postProcessors) {
+ pp = null;
+ try {
+ Class clazz = Class.forName(postProcessor);
+ Object o = clazz.newInstance();
+ pp = (PostProcessor)o;
+ } catch(Exception ex) {
+ logger.error("instanciating post processor",ex);
+ }
+ if(pp!=null) {
+ pp.setConfigData(job);
+ pp.postProcess();
+ }
+ }
+
+ con = PoolManager.getInstance().getConnection();
+ ps=con.prepareStatement("UPDATE EXPORT_JOBS SET STATUS="+ExportJob.STATUS_TERMINATED+" WHERE EXPORT_ID=? AND UTI_LOGIN=?");
+ ps.setLong(1, exportId);
+ ps.setString(2, user);
+ ps.executeUpdate();
+
+ } catch(Exception ex) {
+ logger.error("notifyTerminated()",ex);
+ try {
+ String sql = "UPDATE EXPORT_JOBS SET STATUS="+ExportJob.STATUS_ERROR+", ERROR_MESSAGE=? WHERE EXPORT_ID=? AND UTI_LOGIN=?";
+ if(con==null) con = PoolManager.getInstance().getConnection();
+ PreparedStatement ps = con.prepareStatement(sql);
+ ps.setString(1,ex.getMessage());
+ ps.setLong(2, exportId);
+ ps.setString(3, user);
+ ps.executeUpdate();
+ } catch(SQLException sqlEx) {}
+ // cleanning
+ File generated = new File(job.getGeneratedFileName());
+ if(generated.exists()) {
+ try {
+ FileUtils.dropRecursiveDirectory(generated.getParentFile());
+ } catch(Throwable t) {}
+ }
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ con=null;
+ }
+ }
+ getNotifier().notifyThreadStop(this);
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\t").append(getName()).append(":");
+ if(isAlive()) {
+ sb.append("export running.");
+ if(exportTerminated) {
+ sb.append(" Main export terminated.");
+ if(pp!=null) {
+ sb.append(" Running post-processor ").append(pp.getClass().getName()).append(".");
+ }
+ } else {
+ sb.append(" Main export running.");
+ }
+ } else {
+ if(isStarted()) {
+ sb.append("export fully terminated.");
+ } else {
+ sb.append("idle");
+ }
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+ }
+
+ private class User implements XemeliosUser {
+ private String userId;
+ public User(String userId) {
+ super();
+ this.userId = userId;
+ }
+ @Override
+ public String getId() {
+ return userId;
+ }
+ @Override
+ public String getDisplayName() {
+ return userId;
+ }
+ @Override
+ public boolean hasRole(String role) {
+ return true;
+ }
+ @Override
+ public boolean hasDocument(String document) {
+ return true;
+ }
+ @Override
+ public boolean hasCollectivite(String collectivite, DocumentModel dm) {
+ return true;
+ }
+ }
+
+ private class MyExporter extends Exporter {
+ private ExportRunnerImpl impl;
+ private String undertakerClassName;
+
+ public MyExporter(File f, DataResultSet drs, DocumentModel dm, String etatId, ElementModel em, ConfigModel cf, ExportRunnerImpl notifier, String undertakerClassName) {
+ super(f,drs,dm,etatId,em,cf,ExportRunner.this.getApplicationConfiguration());
+ this.undertakerClassName=undertakerClassName;
+ if(this.undertakerClassName==null || this.undertakerClassName.length()==0) {
+ this.undertakerClassName = "fr.gouv.finances.cp.xemelios.export.JxlExporter";
+ }
+ this.impl=notifier;
+ }
+
+ public void runImmediatly() throws Exception {
+ doExport();
+ cleanAfterRun();
+ impl.notifyTerminated();
+ }
+
+
+
+
+
+ @Override
+ protected void done() {
+logger.debug("MyExporter.done()");
+ super.done();
+ impl.notifyTerminated();
+ }
+
+ @Override
+ protected ExportUndertaker getUndertaker() {
+ try {
+ Class undertakerClass = Class.forName(undertakerClassName);
+ Class[] exporterArgsClass = new Class[]{Exporter.class};
+ Object[] exporterArgs = new Object[]{this};
+ Constructor constructor = undertakerClass.getConstructor(exporterArgsClass);
+ ExportUndertaker undertaker = (ExportUndertaker) constructor.newInstance(exporterArgs);
+
+ return undertaker;
+ } catch (ClassNotFoundException e) {
+ logger.error("",e);
+ return null;
+ } catch (NoSuchMethodException e) {
+ logger.error("",e);
+ return null;
+ } catch (InstantiationException e) {
+ logger.error("",e);
+ return null;
+ } catch (IllegalAccessException e) {
+ logger.error("",e);
+ return null;
+ } catch (IllegalArgumentException e) {
+ logger.error("",e);
+ return null;
+ } catch (InvocationTargetException e) {
+ logger.error("",e);
+ return null;
+ }
+ }
+
+ }
+}
--- /dev/null
+/*
+ *
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 Christophe Marchand <christophe.marchand@axyus.com>
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.exports.postProcessors;
+
+import fr.gouv.finances.dgfip.xemelios.batch.PostProcessor;
+import fr.gouv.finances.dgfip.xemelios.export.ExportJob;
+import java.io.File;
+import java.lang.reflect.Method;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public class ExcelRunner implements PostProcessor {
+ private static final Logger logger = Logger.getLogger(ExcelRunner.class);
+ private ExportJob job;
+
+ public ExcelRunner() {
+ super();
+ }
+
+ public void setConfigData(Object data) {
+ job = (ExportJob)data;
+ }
+
+ public void postProcess() throws Exception {
+ if(job==null) return;
+ File f = new File(job.getGeneratedFileName());
+ if(!f.exists()) return;
+ if(!f.getName().toUpperCase().endsWith(".XLS")) return;
+
+ String osName = System.getProperty("os.name");
+ String url = f.toURL().toExternalForm();
+ try {
+ if (osName.startsWith("Mac OS")) {
+ // Mac OS X can handle file types itself (thank goodness!)
+ Class fileMgr = Class.forName("com.apple.eio.FileManager");
+ Method openURL = fileMgr.getDeclaredMethod("openURL",new Class[] {String.class});
+ openURL.invoke(null, new Object[] {url});
+ } else if (osName.startsWith("Windows")) { // who knows what Windows does ...
+ // il y a un bug avec Windows 2000, il faut que le fichier commence par file:// au lieu de file:/
+ if("Windows 2000".equals(System.getProperty("os.name")) || "Windows 98".equals(System.getProperty("os.name"))) {
+ if(url.startsWith("file:/") && !url.startsWith("file://"))
+ url = "file://".concat(url.substring(6));
+ }
+ Process p = Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
+ // we must synchronize this
+ p.waitFor();
+ } else {
+ logger.error("This post processor - ExcelRunner - can only be used on Windows and MacOS. You are using "+osName);
+ }
+ } catch (Exception e) {
+ logger.error(e);
+ throw e;
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.exports.postProcessors;
+
+import fr.gouv.finances.dgfip.xemelios.batch.PostProcessor;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import fr.gouv.finances.dgfip.xemelios.export.ExportJob;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public class Zipper implements PostProcessor {
+ private static final Logger logger = Logger.getLogger(Zipper.class);
+ private ExportJob job=null;
+
+ public Zipper() {
+ super();
+ }
+
+ public void setConfigData(Object data) {
+ this.job=(ExportJob)data;
+ }
+
+ public void postProcess() throws Exception {
+ if(job==null) throw new Exception("Job is null !");
+ File generatedFile = new File(job.getGeneratedFileName());
+ File directory = generatedFile.getParentFile();
+ final String fileName = generatedFile.getName().concat(".zip");
+ File zipFile = new File(directory,fileName);
+ ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
+ File[] files = directory.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return !name.equals(fileName);
+ }
+ });
+ zos.setLevel(9);
+ for(File f:files) {
+ if(!f.isDirectory()) {
+ ZipEntry ze = new ZipEntry(f.getName());
+ zos.putNextEntry(ze);
+ byte[] buffer = new byte[1024*8];
+ FileInputStream fis = new FileInputStream(f);
+ int read = 0;
+ while((read=fis.read(buffer)) > 0) {
+ zos.write(buffer, 0, read);
+ }
+ fis.close();
+ zos.closeEntry();
+ }
+ }
+ zos.close();
+// zos.finish();
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sql = "UPDATE EXPORT_JOBS SET GENERATED_FILE_NAME=? WHERE EXPORT_ID=? AND UTI_LOGIN=?";
+ PreparedStatement ps = con.prepareStatement(sql);
+ ps.setString(1,zipFile.getAbsolutePath());
+ ps.setLong(2,job.getIdExport());
+ ps.setString(3,job.getOwner());
+ ps.executeUpdate();
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ job.setGeneratedFileName(zipFile.getAbsolutePath());
+ for(File f:files) f.delete();
+ } catch(SQLException sqlEx) {
+ logger.error("while changing name generated file",sqlEx);
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports;
+
+import fr.gouv.finances.dgfip.xemelios.utils.XmlUtils;
+import fr.gouv.finances.dgfip.utils.Pair;
+import fr.gouv.finances.dgfip.utils.xml.FactoryProvider;
+import fr.gouv.finances.dgfip.utils.xml.NamespaceContextImpl;
+import fr.gouv.finances.dgfip.xemelios.common.config.DocumentModel;
+import fr.gouv.finances.dgfip.xemelios.common.config.EtatModel;
+import java.io.File;
+import java.io.IOException;
+import java.util.Stack;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.apache.log4j.Logger;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DefaultHandler2;
+
+/**
+ *
+ * @author chm
+ */
+public class BudgCollParser {
+
+ public static final transient String IGNORABLE_ERROR = "This is not an error, only an expected termination";
+ private File xmlFile;
+ private DocumentModel documentModel;
+ private String collectivite, collectiviteLib, budget, budgetLib, errorMessage;
+ private boolean inError = false;
+
+ public BudgCollParser(File xmlFile, DocumentModel documentModel) {
+ super();
+ this.xmlFile = xmlFile;
+ this.documentModel = documentModel;
+ }
+
+ /**
+ * Start investigation process
+ */
+ public void investigate() {
+ SAXParserFactory saxFactory = FactoryProvider.getSaxParserFactory();
+ ParserHandler ph = new ParserHandler(documentModel);
+ try {
+ SAXParser parser = saxFactory.newSAXParser();
+ parser.parse(xmlFile, ph);
+ } catch (ParserConfigurationException pcEx) {
+ pcEx.printStackTrace();
+ } catch (SAXException saxEx) {
+ if (!saxEx.getMessage().equals(IGNORABLE_ERROR)) {
+ // file is not valid
+ setError(saxEx.getMessage());
+ }
+ } catch(IOException ioEx) {
+ // should never happen
+ ioEx.printStackTrace();
+ } finally {
+ if(ph!=null && !inError) {
+ if(ph.getCollectivite()!=null) {
+ if(ph.collectivite.key!=null && ph.collectivite.key.length()>0 && (collectivite==null || collectivite.length()==0)) {
+ collectivite = ph.collectivite.key;
+ }
+ if(ph.collectivite.libelle!=null && ph.collectivite.libelle.length()>0 && (collectiviteLib==null || collectiviteLib.length()==0)) {
+ collectiviteLib = ph.collectivite.libelle;
+ }
+ }
+ if(ph.budget!=null) {
+ if(ph.budget.key!=null && ph.budget.key.length()>0 && (budget==null || budget.length()==0)) {
+ budget = ph.budget.key;
+ }
+ if(ph.budget.libelle!=null && ph.budget.libelle.length()>0 && (budgetLib==null || budgetLib.length()==0)) {
+ budgetLib = ph.budget.libelle;
+ }
+ }
+ }
+ }
+ }
+
+ public String getBudget() {
+ return budget;
+ }
+
+ public void setBudget(String budget) {
+ this.budget = budget;
+ }
+
+ public String getBudgetLib() {
+ return budgetLib;
+ }
+
+ public void setBudgetLib(String budgetLib) {
+ this.budgetLib = budgetLib;
+ }
+
+ public String getCollectivite() {
+ return collectivite;
+ }
+
+ public void setCollectivite(String collectivite) {
+ this.collectivite = collectivite;
+ }
+
+ public String getCollectiviteLib() {
+ return collectiviteLib;
+ }
+
+ public void setCollectiviteLib(String collectiviteLib) {
+ this.collectiviteLib = collectiviteLib;
+ }
+
+ public void setError(String errorMessage) {
+ inError = true;
+ this.errorMessage = errorMessage;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public boolean isInError() {
+ return inError;
+ }
+
+ private static class ParserHandler extends DefaultHandler2 {
+ private static final Logger logger = Logger.getLogger(ParserHandler.class);
+ private NamespaceContextImpl nsCtx;
+ private Stack<String> tagStack = new Stack<String>();
+ private Stack<StringBuilder> charactersStack = new Stack<StringBuilder>();
+
+ private DocumentModel dm;
+ private Pair budget, collectivite;
+
+ public ParserHandler(DocumentModel dm) {
+ super();
+ this.dm = dm;
+ nsCtx = new NamespaceContextImpl();
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ String tagName = XmlUtils.getShortTagName(uri, localName, qName);
+ switch (tagStack.size()) {
+ case 0: {
+ // si ce n'est pas le tag du doc que l'on importe, bye
+ if (!tagName.equals(dm.getBalise())) {
+ throw new SAXException("Le fichier importé n'est pas un " + dm.getTitre());
+ }
+ break;
+ }
+ case 1: {
+ if (dm.getEntetes().contains(tagName)) {
+ } else if (dm.getReferentiel().equals(tagName)) {
+ } else {
+ EtatModel em = dm.getEtatByTagName(tagName);
+ if(em!=null) throw new SAXException(IGNORABLE_ERROR);
+ }
+ break;
+ }
+ case 2: {
+ break;
+ }
+ }
+ tagStack.push(tagName);
+ charactersStack.push(new StringBuilder());
+
+ String path = XmlUtils.getPath(tagStack);
+ for (int i = 0; i < attributes.getLength(); i++) {
+ String attrName = attributes.getLocalName(i);
+ String value = attributes.getValue(i);
+ String fullPath = path + "/@" + attrName;
+ checkBudgetCollectivite(fullPath, value);
+ }
+ }
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ String tagName = XmlUtils.getShortTagName(uri, localName, qName);
+ if(tagStack.size()==1) {
+ if (!tagName.equals(dm.getBalise())) {
+ throw new SAXException("Fermeture d'un element root inattendu");
+ }
+ }
+ String path = XmlUtils.getPath(tagStack);
+ String innerData = charactersStack.pop().toString();
+ checkBudgetCollectivite(path, innerData);
+ tagStack.pop();
+ }
+
+ @Override
+ public void endPrefixMapping(String prefix) throws SAXException {
+ super.endPrefixMapping(prefix);
+ nsCtx.removeMapping(prefix);
+ }
+
+ @Override
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ super.startPrefixMapping(prefix, uri);
+ nsCtx.addMapping(prefix, uri);
+ }
+
+ private void checkBudgetCollectivite(String path, String value) throws SAXException {
+// logger.debug("checking coll/budg at"+path);
+ if (dm.getBudgetPath() != null) {
+ if (dm.getBudgetPath().getCodePath() != null && path.equals(dm.getBudgetPath().getCodePath().getPath())) {
+ if (budget == null) {
+ budget = new Pair();
+ }
+ budget.key = value;
+ }
+ if (dm.getBudgetPath().getLibellePath() != null && path.equals(dm.getBudgetPath().getLibellePath().getPath())) {
+ if (budget == null) {
+ budget = new Pair();
+ }
+ budget.libelle = value;
+ }
+ }
+ if (dm.getCollectivitePath() != null) {
+ if (dm.getCollectivitePath().getCodePath() != null && path.equals(dm.getCollectivitePath().getCodePath().getPath())) {
+ if (collectivite == null) {
+ collectivite = new Pair();
+ }
+ collectivite.key = value;
+ }
+ if (dm.getCollectivitePath().getLibellePath() != null && path.equals(dm.getCollectivitePath().getLibellePath().getPath())) {
+ if (collectivite == null) {
+ collectivite = new Pair();
+ }
+ collectivite.libelle = value;
+ }
+ }
+ if(collectivite!=null &&collectivite.key!=null && collectivite.key.length()>0 && collectivite.libelle!=null && collectivite.libelle.length()>0
+ && budget!=null && budget.key!=null && budget.key.length()>0 && budget.libelle!=null && budget.libelle.length()>0) {
+ throw new SAXException(IGNORABLE_ERROR);
+ }
+ }
+
+ public Pair getBudget() {
+ return budget;
+ }
+
+ public Pair getCollectivite() {
+ return collectivite;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports;
+
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.batch.BatchRunner;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOFull;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOPK;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOWrapper;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.XemImportsFilesVOFull;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.XemImportsFilesVOWrapper;
+import fr.gouv.finances.dgfip.xemelios.common.Constants;
+import fr.gouv.finances.dgfip.xemelios.common.PJRef;
+import fr.gouv.finances.dgfip.xemelios.common.config.DocumentsModel;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import fr.gouv.finances.dgfip.xemelios.utils.FileUtils;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import org.apache.log4j.Logger;
+
+/**
+ * Ce batch vérifie que toutes les conditions sont bien remplies pour réaliser un import
+ * @author chm
+ */
+public class ImportChecker extends Batch {
+ private final static Logger logger = Logger.getLogger(ImportChecker.class);
+ public static final int MAX_CONCURRENT_THREADS = 3;
+ private int maxConcurrentThreads = MAX_CONCURRENT_THREADS;
+
+ private String importDirectory = null;
+
+ private ThreadPool<ImportCheckerImpl> pool = null;
+
+ public ImportChecker(String[] args) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ String sTmp = getProps().getProperty("max.concurrent.threads");
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ maxConcurrentThreads = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ Connection con = null;
+ Statement st = null;
+ ResultSet rs = null;
+ ArrayList<ImportCheckerImpl> threads = new ArrayList<ImportCheckerImpl>();
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sqlParam = "SELECT PARAM_VALUE FROM PARAMETERS WHERE PARAM_NAME='import.directory'";
+ st = con.createStatement();
+ rs = st.executeQuery(sqlParam);
+ if(rs.next()) {
+ importDirectory = rs.getString(1);
+ rs.close();
+ } else {
+ throw new Exception("parameter 'import.directory' not set !");
+ }
+ String sql = "SELECT IMPORT_ID FROM XEM_IMPORTS WHERE STATUS=0 AND CLEANED IS NULL";
+ rs = st.executeQuery(sql);
+ while(rs.next()) {
+ threads.add(new ImportCheckerImpl(rs.getString(1),importDirectory,BatchRunner.getInstance().getDocuments()));
+ }
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ pool = new ThreadPool<ImportCheckerImpl>(threads);
+ pool.start(maxConcurrentThreads);
+ } catch(SQLException sqlEx) {
+ // TODO
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "import.checker resume";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "import.checker";
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+ sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+ for(RunnableBatch rb: pool.getThreads()) {
+ sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+ if(rb.isAlive()) sb.append(rb.getInformations());
+ }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+ protected class ImportCheckerImpl extends RunnableBatch {
+ private final Logger logger = Logger.getLogger(ImportCheckerImpl.class);
+ private String importId;
+ private ImportVOFull importFull;
+ private List<XemImportsFilesVOFull> files;
+ // utilities
+ private File importDirectory;
+ private DocumentsModel documents;
+ public ImportCheckerImpl(String importId,String importDirectory, DocumentsModel documents) {
+ setName("importChecker<"+importId+">");
+ this.importId=importId;
+ this.importDirectory = new File(importDirectory);
+ this.documents=documents;
+ setName("ImportCheckerImpl<"+importId+">");
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void run() {
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ loadImportInfos(con);
+ importFull.setStatus(1);
+ ImportVOWrapper.updateImportVO(con, importFull);
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ checkFile();
+ con = PoolManager.getInstance().getConnection();
+ ImportVOWrapper.updateImportVO(con, importFull);
+ } catch(SQLException sqlEx) {
+ logger.error("run<"+importId+">()", sqlEx);
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ getNotifier().notifyThreadStop(this);
+ }
+ }
+
+ protected boolean checkFile() {
+ File[] ret = new File[1];
+ ret[0] = new File(new File(importDirectory,importId),importFull.getFileName());
+ ImportContent ic = new ImportContent();
+ for (int i = 0; i < ret.length; i++) {
+ if (ret[i].getName().toLowerCase().endsWith(".zip")) {
+ if (ret[i].exists()) {
+ ZipFile zf = null;
+ try {
+ zf = new ZipFile(ret[i]);
+ for (Enumeration<? extends ZipEntry> enumer = zf.entries(); enumer.hasMoreElements();) {
+ ZipEntry ze = enumer.nextElement();
+ if (!ze.isDirectory()) {
+ String fileName = ze.getName();
+ String entryName = fileName.toLowerCase();
+ fileName = fileName.replace(
+ File.pathSeparatorChar, '_').replace(
+ File.separatorChar, '_').replace(':',
+ '|').replace('\'', '_').replace('/',
+ '_');
+ logger.debug(entryName);
+ if(PJRef.isPJ(ze)) {
+ PJRef pj = new PJRef(ze);
+ pj.writeTmpFile(FileUtils.getTempDir(),zf);
+ ic.pjs.add(pj);
+ } else if ((entryName.endsWith(documents.getDocumentById(importFull.getFileType()).getExtension().toLowerCase()) || entryName.endsWith(".xml")) && !fileName.startsWith("_")) {
+ // on decompresse le fichier dans le
+ // repertoire temporaire, comme ca il sera
+ // supprime en quittant
+ InputStream is = zf.getInputStream(ze);
+ BufferedInputStream bis = new BufferedInputStream(is);
+ File output = new File(FileUtils.getTempDir(), fileName);
+ BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(output));
+ byte[] buffer = new byte[1024];
+ int read = bis.read(buffer);
+ while (read > 0) {
+ bos.write(buffer, 0, read);
+ read = bis.read(buffer);
+ }
+ bos.flush();
+ bos.close();
+ bis.close();
+ ic.filesToImport.add(output);
+ }
+ }
+ }
+ zf.close();
+ } catch (ZipException zEx) {
+ String errorMessage = "Le fichier "+ret[i].getName()+ " n'est pas une archive ZIP valide";
+ importFull.setErrorMessage(errorMessage);
+ } catch (IOException ioEx) {
+ String errorMessage = "Le fichier "+ret[i].getName()+" est illisible. Vérifiez que les noms des fichiers\ncontenus dans l'archive ne comportent pas de caractères spéciaux ou accentués.";
+ importFull.setErrorMessage(errorMessage);
+ } finally {
+ if(zf!=null) {
+ try { zf.close(); } catch(Throwable t) {}
+ }
+ }
+ }
+ } else if(ret[i].getName().toLowerCase().endsWith(".gz")) {
+ try {
+ String fileName = ret[i].getName();
+ fileName = fileName.substring(0, fileName.length()-3);
+ File output = new File(FileUtils.getTempDir(), fileName);
+ GZIPInputStream gis = new GZIPInputStream(new FileInputStream(ret[i]));
+ BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(output));
+ byte[] buffer = new byte[1024];
+ int read = gis.read(buffer);
+ while (read > 0) {
+ bos.write(buffer, 0, read);
+ read = gis.read(buffer);
+ }
+ bos.flush();
+ bos.close();
+ gis.close();
+ ic.filesToImport.add(output);
+ } catch(IOException ioEx) {
+ // nothing to do
+ }
+ } else {
+ ic.filesToImport.add(ret[i]);
+ }
+ }
+ if(ic.filesToImport.size()==1) {
+ if(Constants.XEMELIOS_ARCHIVE_SIGN.equals(importFull.getFileType())) {
+ // Traitement des archives
+ importFull.setStatus(6);
+ } else {
+ // Traitement des autres fichiers
+ boolean needToLookForCollBudg = false;
+ StringBuffer errors = new StringBuffer();
+ if(importFull.getCollectivite()==null || importFull.getCollectivite().length()==0) {
+ needToLookForCollBudg = true;
+ }
+ if(importFull.getCollectiviteLib()==null || importFull.getCollectiviteLib().length()==0) {
+ needToLookForCollBudg = true;
+ }
+ if(importFull.getBudget()==null || importFull.getBudget().length()==0) {
+ needToLookForCollBudg = true;
+ }
+ if(importFull.getBudgetLib()==null || importFull.getBudgetLib().length()==0) {
+ needToLookForCollBudg = true;
+ }
+ if(needToLookForCollBudg) {
+ BudgCollParser bcp = new BudgCollParser(ic.filesToImport.get(0), documents.getDocumentById(importFull.getFileType()));
+ bcp.investigate();
+ if(bcp.isInError()) {
+ importFull.setErrorMessage(bcp.getErrorMessage());
+ importFull.setStatus(5);
+ } else {
+ if(importFull.getCollectivite()==null || importFull.getCollectivite().length()==0) {
+ importFull.setCollectivite(bcp.getCollectivite());
+ }
+ if(importFull.getCollectiviteLib()==null || importFull.getCollectiviteLib().length()==0) {
+ importFull.setCollectiviteLib(bcp.getCollectiviteLib());
+ }
+ if(importFull.getBudget()==null || importFull.getBudget().length()==0) {
+ importFull.setBudget(bcp.getBudget());
+ }
+ if(importFull.getBudgetLib()==null || importFull.getBudgetLib().length()==0) {
+ importFull.setBudgetLib(bcp.getBudgetLib());
+ }
+ importFull.determinateStatus();
+ }
+ }
+ }
+ } else {
+ // TODO: multi sub files
+ }
+ // TODO
+ return false;
+ }
+ @SuppressWarnings("unchecked")
+ public void loadImportInfos(Connection con) throws SQLException {
+ ImportVOPK pk = new ImportVOPK(importId);
+ importFull = ImportVOWrapper.getImportVOFullByPk(con, pk);
+ files = XemImportsFilesVOWrapper.getAllXemImportsFilesVOFullBy(con, XemImportsFilesVOFull.class, "SELECT "+XemImportsFilesVOWrapper.getSelectFieldsClause()+" FROM XEM_IMPORTS_FILES WHERE IMPORT_ID='"+importId+"'");
+ }
+
+ @Override
+ public String getInformations() {
+ if(isAlive()) return "\t".concat(getName()).concat(": running\n");
+ else return "\t".concat(getName()).concat(": idle\n");
+ }
+ }
+ public static class ImportContent {
+ ArrayList<File> filesToImport;
+ ArrayList<PJRef> pjs;
+ public ImportContent() {
+ super();
+ filesToImport = new ArrayList<File>();
+ pjs = new ArrayList<PJRef>();
+ }
+ public void setFilesToImport(ArrayList<File> array){
+ this.filesToImport=array;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports;
+
+import fr.gouv.finances.cp.xemelios.importers.batch.BatchRealImporter;
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.batch.BatchRunner;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOFull;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOPK;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOWrapper;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import java.io.File;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author chm
+ */
+public class Importer extends Batch {
+ public static final int MAX_CONCURRENT_THREADS = 3;
+ private int maxConcurrentThreads = MAX_CONCURRENT_THREADS;
+ private String documentsDefDirs = null;
+
+ private String importDirectory = null;
+
+ private ThreadPool<ImporterImpl> pool = null;
+
+ public Importer(String[] args) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ String sTmp = getProps().getProperty("max.concurrent.threads");
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ maxConcurrentThreads = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ Connection con = null;
+ Statement st = null;
+ ResultSet rs = null;
+ ArrayList<ImporterImpl> threads = new ArrayList<ImporterImpl>();
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sqlParam = "SELECT PARAM_VALUE FROM PARAMETERS WHERE PARAM_NAME='import.directory'";
+ st = con.createStatement();
+ rs = st.executeQuery(sqlParam);
+ if(rs.next()) {
+ importDirectory = rs.getString(1);
+ rs.close();
+ } else {
+ throw new Exception("parameter 'import.directory' not set !");
+ }
+ StringBuffer select = new StringBuffer();
+ String sql = "SELECT IMPORT_ID FROM XEM_IMPORTS WHERE STATUS=6";
+ rs = st.executeQuery(sql);
+ while(rs.next()) {
+ threads.add(new ImporterImpl(rs.getString(1),importDirectory,documentsDefDirs));
+ }
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ pool = new ThreadPool<ImporterImpl>(threads);
+ pool.start(maxConcurrentThreads);
+ } catch(SQLException sqlEx) {
+ sqlEx.printStackTrace();
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "resume importer";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "importer";
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+ sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+ for(RunnableBatch rb: pool.getThreads()) {
+ sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+ if(rb.isAlive()) sb.append(rb.getInformations());
+ }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+ private class ImporterImpl extends RunnableBatch {
+ private String importId;
+ private String importDirectory;
+ private String confDir;
+
+ // utilities
+ ImportVOFull importFull=null;
+
+ public ImporterImpl(String importId, String importDirectory, String confDir) {
+ this.importId=importId;
+ this.importDirectory=importDirectory;
+ this.confDir = confDir;
+ setName("ImporterImpl<".concat(importId).concat(">"));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void run() {
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ loadImportInfos(con);
+ importFull.setStatus(3);
+ ImportVOWrapper.updateImportVO(con, importFull);
+ PoolManager.getInstance().releaseConnection(con); con=null;
+
+// String args[] = new String[] {
+// "-g", confDir,
+// "-d",importFull.getFileType(),
+// "-b",importFull.getBudget(),importFull.getBudgetLib(),
+// "-c",importFull.getCollectivite(),importFull.getCollectiviteLib(),
+// "-u",importFull.getUtiLogin(),
+// "-i","no","no",
+// "-f",new File(new File(new File(importDirectory),importFull.getImportId()),importFull.getFileName()).getAbsolutePath()
+// };
+
+ ArrayList<String> argList = new ArrayList<String>();
+ argList.add("-g"); argList.add(confDir);
+ argList.add("-d"); argList.add(importFull.getFileType());
+ if(importFull.getBudget()!=null && importFull.getBudgetLib()!=null) {
+ argList.add("-b"); argList.add(importFull.getBudget()); argList.add(importFull.getBudgetLib());
+ }
+ if(importFull.getCollectivite()!=null && importFull.getCollectiviteLib()!=null) {
+ argList.add("-c"); argList.add(importFull.getCollectivite()); importFull.getCollectiviteLib();
+ }
+ argList.add("-u"); argList.add(importFull.getUtiLogin());
+ argList.add("-i"); argList.add("no"); argList.add("no");
+ argList.add("-f"); argList.add(new File(new File(new File(importDirectory),importFull.getImportId()),importFull.getFileName()).getAbsolutePath());
+
+
+
+
+// args[i++] = "-g";
+// args[i++] = confDir;
+// args[i++] = "-d";
+// args[i++] = importFull.getFileType();
+// args[i++] = "-b";
+// args[i++] = importFull.getBudget();
+// args[i++] = importFull.getBudgetLib();
+// args[i++] = "-c";
+// args[i++] = importFull.getCollectivite();
+// args[i++] = importFull.getCollectiviteLib();
+// args[i++] = "-u";
+// args[i++] = importFull.getUtiLogin();
+// args[i++] = "-i";
+// args[i++] = "no";
+// args[i++] = "no";
+// args[i++] = "-f";
+// args[i++] = new File(new File(new File(importDirectory),importFull.getImportId()),importFull.getFileName()).getAbsolutePath();
+ String[] args = new String[argList.size()];
+ args = argList.toArray(args);
+ BatchRealImporter.main(args);
+ importFull.setStatus(4);
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ importFull.setStatus(5);
+ importFull.setErrorMessage(ex.getMessage());
+ } finally {
+ try {
+ if(con==null) con=PoolManager.getInstance().getConnection();
+ ImportVOWrapper.updateImportVO(con, importFull);
+ } catch (SQLException ex1) {
+ ex1.printStackTrace();
+ }
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ }
+ getNotifier().notifyThreadStop(this);
+ }
+ }
+
+
+ public void loadImportInfos(Connection con) throws SQLException {
+ ImportVOPK pk = new ImportVOPK(importId);
+ importFull = ImportVOWrapper.getImportVOFullByPk(con, pk);
+ }
+
+ @Override
+ public String getInformations() {
+ if(isAlive()) return "\t".concat(getName()).concat(": running\n");
+ else return "\t".concat(getName()).concat(": idle\n");
+ }
+
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports;
+
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOFull;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOPK;
+import fr.gouv.finances.dgfip.xemelios.batch.imports.utils.ImportVOWrapper;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.JdbcUtils;
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.PStmtBinder;
+import java.io.File;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author chm
+ */
+public class PostImportCleaner extends Batch {
+ public static final int MAX_CONCURRENT_THREADS = 3;
+ private int maxConcurrentThreads = MAX_CONCURRENT_THREADS;
+ private String importDirectory = null;
+
+ private ThreadPool<PostImportCleanerImpl> pool = null;
+
+ public PostImportCleaner(String args[]) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ String sTmp = getProps().getProperty("max.concurrent.threads");
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ maxConcurrentThreads = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ }
+
+
+
+ @Override
+ protected void doProcess() throws Exception {
+ Connection con = null;
+ Statement st = null;
+ ResultSet rs = null;
+ ArrayList<PostImportCleanerImpl> threads = new ArrayList<PostImportCleanerImpl>();
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sqlParam = "SELECT PARAM_VALUE FROM PARAMETERS WHERE PARAM_NAME='import.directory'";
+ st = con.createStatement();
+ rs = st.executeQuery(sqlParam);
+ if(rs.next()) {
+ importDirectory = rs.getString(1);
+ rs.close();
+ } else {
+ throw new Exception("parameter 'import.directory' not set !");
+ }
+ String sql = "SELECT IMPORT_ID FROM XEM_IMPORTS WHERE STATUS IN (4,5) AND CLEANED IS NULL";
+ rs = st.executeQuery(sql);
+ while(rs.next()) {
+ threads.add(new PostImportCleanerImpl(rs.getString(1),importDirectory));
+ }
+ PoolManager.getInstance().releaseConnection(con); con=null;
+ pool = new ThreadPool<PostImportCleanerImpl>(threads);
+ pool.start(maxConcurrentThreads);
+ } catch(SQLException sqlEx) {
+ // TODO
+ } finally {
+ if(con!=null) PoolManager.getInstance().releaseConnection(con);
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "post-import.cleaner.resume";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "post-import.cleaner";
+
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+ sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+ for(RunnableBatch rb: pool.getThreads()) {
+ sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+ if(rb.isAlive()) sb.append(rb.getInformations());
+ }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+ private class PostImportCleanerImpl extends RunnableBatch {
+ private final Logger logger = Logger.getLogger(PostImportCleanerImpl.class);
+ private String importId;
+ private String importDirectory;
+ // utilities
+ private ImportVOFull importFull;
+
+ public PostImportCleanerImpl(String importId, String importDirectory) {
+ this.importDirectory=importDirectory;
+ this.importId=importId;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void run() {
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ loadImportInfos(con);
+ File directory = new File(new File(importDirectory),importFull.getImportId());
+ File sourceFile = new File(directory,importFull.getFileName());
+ ArrayList<File> excludeFiles = new ArrayList<File>();
+ if(importFull.getStatus()==5) {
+ excludeFiles.add(sourceFile);
+ }
+ cleanDirectory(directory,excludeFiles);
+ JdbcUtils.executeUpdate(con,"UPDATE XEM_IMPORTS SET CLEANED=1 WHERE IMPORT_ID=?",new PStmtBinder.SimplePStmtBinderBuilder().add(importId).toPStmtBinder());
+ } catch(SQLException sqlEx) {
+ logger.error("PostImportCleanerImpl.run()",sqlEx);
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ }
+ getNotifier().notifyThreadStop(this);
+ }
+ }
+
+ private void cleanDirectory(File directory, List<File> excludes) {
+ for(File f:directory.listFiles()) {
+ if(excludes.contains(f)) continue;
+ else if(f.isDirectory()) {
+ cleanDirectory(f, excludes);
+ } else {
+ f.delete();
+ }
+ }
+ if(directory.listFiles().length==0 && !excludes.contains(directory)) {
+ directory.delete();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void loadImportInfos(Connection con) throws SQLException {
+ ImportVOPK pk = new ImportVOPK(importId);
+ importFull = ImportVOWrapper.getImportVOFullByPk(con, pk);
+// files = XemImportsFilesVOWrapper.getAllXemImportsFilesVOFullBy(con, XemImportsFilesVOFull.class, "SELECT "+XemImportsFilesVOWrapper.getSelectFieldsClause()+" FROM XEM_IMPORTS_FILES WHERE IMPORT_ID='"+importId+"'");
+ }
+
+ @Override
+ public String getInformations() {
+ if(isAlive()) return "\t".concat(getName()).concat(": running\n");
+ else return "\t".concat(getName()).concat(": idle\n");
+ }
+
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import java.sql.Timestamp;
+import org.apache.log4j.Logger;
+
+public class ImportVOFull extends ImportVOPK implements java.io.Serializable {
+ private static final Logger logger = Logger.getLogger(ImportVOFull.class);
+
+ /**
+ * MAPS UTI_LOGIN column.
+ */
+ protected java.lang.String utiLogin;
+ protected boolean isUtiLoginSet = false;
+ protected boolean isUtiLoginModified = false;
+ /**
+ * MAPS FILE_NAME column.
+ */
+ protected java.lang.String fileName;
+ protected boolean isFileNameSet = false;
+ protected boolean isFileNameModified = false;
+ /**
+ * MAPS FILE_TYPE column.
+ */
+ protected java.lang.String fileType;
+ protected boolean isFileTypeSet = false;
+ protected boolean isFileTypeModified = false;
+ /**
+ * MAPS SUBMIT_DATE column.
+ */
+ protected java.sql.Timestamp submitDate;
+ protected boolean isSubmitDateSet = false;
+ protected boolean isSubmitDateModified = false;
+ /**
+ * MAPS END_DATE column.
+ */
+ protected java.sql.Timestamp endDate;
+ protected boolean isEndDateSet = false;
+ protected boolean isEndDateModified = false;
+ /**
+ * MAPS STATUS column.
+ */
+ protected java.lang.Integer status;
+ protected boolean isStatusSet = false;
+ protected boolean isStatusModified = false;
+ /**
+ * MAPS COLLECTIVITE column.
+ */
+ protected java.lang.String collectivite;
+ protected boolean isCollectiviteSet = false;
+ protected boolean isCollectiviteModified = false;
+ /**
+ * MAPS BUDGET column.
+ */
+ protected java.lang.String budget;
+ protected boolean isBudgetSet = false;
+ protected boolean isBudgetModified = false;
+ /**
+ * MAPS COLLECTIVITE_LIB column.
+ */
+ protected java.lang.String collectiviteLib;
+ protected boolean isCollectiviteLibSet = false;
+ protected boolean isCollectiviteLibModified = false;
+ /**
+ * MAPS BUDGET_LIB column.
+ */
+ protected java.lang.String budgetLib;
+ protected boolean isBudgetLibSet = false;
+ protected boolean isBudgetLibModified = false;
+ /**
+ * MAPS ERROR_MESSAGE column.
+ */
+ protected java.lang.String errorMessage;
+ protected boolean isErrorMessageSet = false;
+ protected boolean isErrorMessageModified = false;
+
+ /**
+ * Default Constructor
+ */
+ public ImportVOFull() {
+ super();
+ }
+
+ /**
+ * Constructs a new Full object, initializing only PK fileds.
+ */
+ public ImportVOFull(java.lang.String importId) {
+ super(importId);
+ }
+
+ public ImportVOFull(ResultSet rs) throws SQLException {
+ this();
+ int i = 1;
+ setInnerUtiLogin(rs.getString(i++));
+ setInnerImportId(rs.getString(i++));
+ setInnerFileName(rs.getString(i++));
+ setInnerFileType(rs.getString(i++));
+ try {
+ setInnerSubmitDate(rs.getTimestamp(i++));
+ } catch(SQLException sqlEx) {
+ // mysql jdbc driver throws a SQLException when value is null
+ }
+ try {
+ setInnerEndDate(rs.getTimestamp(i++));
+ } catch(SQLException sqlEx) {
+ // mysql jdbc driver throws a SQLException when value is null
+ }
+ int statusTmp = rs.getInt(i++);
+ if (!rs.wasNull()) {
+ setInnerStatus(new java.lang.Integer(statusTmp));
+ }
+ setInnerCollectivite(rs.getString(i++));
+ setInnerBudget(rs.getString(i++));
+ setInnerCollectiviteLib(rs.getString(i++));
+ setInnerBudgetLib(rs.getString(i++));
+ setInnerErrorMessage(rs.getString(i++));
+ }
+
+ public java.lang.String getUtiLogin() {
+ return utiLogin;
+ }
+
+ public void setUtiLogin(java.lang.String utiLogin) {
+ this.utiLogin = utiLogin;
+ this.isUtiLoginModified = true;
+ }
+
+ protected void setInnerUtiLogin(java.lang.String utiLogin) {
+ this.utiLogin = utiLogin;
+ this.isUtiLoginSet = true;
+ }
+
+ public java.lang.String getStrUtiLogin(java.lang.String returnInCaseOfNull) {
+ return utiLogin != null ? utiLogin.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(java.lang.String fileName) {
+ this.fileName = fileName;
+ this.isFileNameModified = true;
+ }
+
+ protected void setInnerFileName(java.lang.String fileName) {
+ this.fileName = fileName;
+ this.isFileNameSet = true;
+ }
+
+ public java.lang.String getStrFileName(java.lang.String returnInCaseOfNull) {
+ return fileName != null ? fileName.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.String getFileType() {
+ return fileType;
+ }
+
+ public void setFileType(java.lang.String fileType) {
+ this.fileType = fileType;
+ this.isFileTypeModified = true;
+ }
+
+ protected void setInnerFileType(java.lang.String fileType) {
+ this.fileType = fileType;
+ this.isFileTypeSet = true;
+ }
+
+ public java.lang.String getStrFileType(java.lang.String returnInCaseOfNull) {
+ return fileType != null ? fileType.toString() : returnInCaseOfNull;
+ }
+
+ public java.sql.Timestamp getSubmitDate() {
+ return submitDate;
+ }
+
+ public void setSubmitDate(java.sql.Timestamp submitDate) {
+ this.submitDate = submitDate;
+ this.isSubmitDateModified = true;
+ }
+
+ protected void setInnerSubmitDate(java.sql.Timestamp submitDate) {
+ this.submitDate = submitDate;
+ this.isSubmitDateSet = true;
+ }
+
+ public java.lang.String getStrSubmitDate(java.lang.String returnInCaseOfNull) {
+ return submitDate != null ? submitDate.toString() : returnInCaseOfNull;
+ }
+
+ public java.sql.Timestamp getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(java.sql.Timestamp endDate) {
+ this.endDate = endDate;
+ this.isEndDateModified = true;
+ }
+
+ protected void setInnerEndDate(java.sql.Timestamp endDate) {
+ this.endDate = endDate;
+ this.isEndDateSet = true;
+ }
+
+ public java.lang.String getStrEndDate(java.lang.String returnInCaseOfNull) {
+ return endDate != null ? endDate.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(java.lang.Integer status) {
+ this.status = status;
+ this.isStatusModified = true;
+ if(status==5 || status==4)
+ setEndDate(new Timestamp(System.currentTimeMillis()));
+
+ }
+
+ protected void setInnerStatus(java.lang.Integer status) {
+ this.status = status;
+ this.isStatusSet = true;
+ }
+
+ public java.lang.String getStrStatus(java.lang.String returnInCaseOfNull) {
+ return status != null ? status.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.String getCollectivite() {
+ return collectivite;
+ }
+
+ public void setCollectivite(java.lang.String collectivite) {
+ this.collectivite = collectivite;
+ this.isCollectiviteModified = true;
+ }
+
+ protected void setInnerCollectivite(java.lang.String collectivite) {
+ this.collectivite = collectivite;
+ this.isCollectiviteSet = true;
+ }
+
+ public java.lang.String getStrCollectivite(java.lang.String returnInCaseOfNull) {
+ return collectivite != null ? collectivite.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.String getBudget() {
+ return budget;
+ }
+
+ public void setBudget(java.lang.String budget) {
+ this.budget = budget;
+ this.isBudgetModified = true;
+ }
+
+ protected void setInnerBudget(java.lang.String budget) {
+ this.budget = budget;
+ this.isBudgetSet = true;
+ }
+
+ public java.lang.String getStrBudget(java.lang.String returnInCaseOfNull) {
+ return budget != null ? budget.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.String getCollectiviteLib() {
+ return collectiviteLib;
+ }
+
+ public void setCollectiviteLib(java.lang.String collectiviteLib) {
+ this.collectiviteLib = collectiviteLib;
+ this.isCollectiviteLibModified = true;
+ }
+
+ protected void setInnerCollectiviteLib(java.lang.String collectiviteLib) {
+ this.collectiviteLib = collectiviteLib;
+ this.isCollectiviteLibSet = true;
+ }
+
+ public java.lang.String getStrCollectiviteLib(java.lang.String returnInCaseOfNull) {
+ return collectiviteLib != null ? collectiviteLib.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.String getBudgetLib() {
+ return budgetLib;
+ }
+
+ public void setBudgetLib(java.lang.String budgetLib) {
+ this.budgetLib = budgetLib;
+ this.isBudgetLibModified = true;
+ }
+
+ protected void setInnerBudgetLib(java.lang.String budgetLib) {
+ this.budgetLib = budgetLib;
+ this.isBudgetLibSet = true;
+ }
+
+ public java.lang.String getStrBudgetLib(java.lang.String returnInCaseOfNull) {
+ return budgetLib != null ? budgetLib.toString() : returnInCaseOfNull;
+ }
+
+ public java.lang.String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(java.lang.String errorMessage) {
+ this.errorMessage = errorMessage;
+ this.isErrorMessageModified = true;
+ }
+
+ protected void setInnerErrorMessage(java.lang.String errorMessage) {
+ this.errorMessage = errorMessage;
+ this.isErrorMessageSet = true;
+ }
+
+ public java.lang.String getStrErrorMessage(java.lang.String returnInCaseOfNull) {
+ return errorMessage != null ? errorMessage.toString() : returnInCaseOfNull;
+ }
+
+ public void validate() throws IllegalStateException {
+ if (utiLogin == null) {
+ throw new IllegalStateException("UTI_LOGIN " + VoConstants.NOT_NULL_MSG);
+ }
+ if (utiLogin != null && utiLogin.length() > UTI_LOGIN_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "UTI_LOGIN" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (importId == null) {
+ throw new IllegalStateException("IMPORT_ID " + VoConstants.NOT_NULL_MSG);
+ }
+ if (importId != null && importId.length() > IMPORT_ID_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "IMPORT_ID" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (fileName == null) {
+ throw new IllegalStateException("FILE_NAME " + VoConstants.NOT_NULL_MSG);
+ }
+ if (fileName != null && fileName.length() > FILE_NAME_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "FILE_NAME" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (fileType == null) {
+ throw new IllegalStateException("FILE_TYPE " + VoConstants.NOT_NULL_MSG);
+ }
+ if (fileType != null && fileType.length() > FILE_TYPE_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "FILE_TYPE" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (status == null) {
+ throw new IllegalStateException("STATUS " + VoConstants.NOT_NULL_MSG);
+ }
+ if (collectivite != null && collectivite.length() > COLLECTIVITE_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "COLLECTIVITE" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (budget != null && budget.length() > BUDGET_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "BUDGET" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (collectiviteLib != null && collectiviteLib.length() > COLLECTIVITE_LIB_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "COLLECTIVITE_LIB" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (budgetLib != null && budgetLib.length() > BUDGET_LIB_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "BUDGET_LIB" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ if (errorMessage != null && errorMessage.length() > ERROR_MESSAGE_LEN) {
+ throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX + "ERROR_MESSAGE" + VoConstants.TOO_LONG_MSG_SUFX);
+ }
+ }
+ public void determinateStatus() {
+ if(status==5) return;
+ boolean correct = true;
+ if(collectivite==null || collectivite.length()==0) correct = false;
+ if(collectiviteLib==null || collectiviteLib.length()==0) correct = false;
+ if(budget==null || budget.length()==0) correct=false;
+ if(budgetLib==null || budgetLib.length()==0) correct=false;
+ if(fileType==null || fileType.length()==0) correct=false;
+ if(correct) setStatus(6);
+ else setStatus(2);
+ }
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+
+public class ImportVOPK implements java.io.Serializable {
+
+ public static final int UTI_LOGIN_LEN = 50;
+ public static final int IMPORT_ID_LEN = 200;
+ public static final int FILE_NAME_LEN = 200;
+ public static final int FILE_TYPE_LEN = 200;
+ public static final int SUBMIT_DATE_LEN = 0;
+ public static final int END_DATE_LEN = 0;
+ public static final int STATUS_LEN = 10;
+ public static final int COLLECTIVITE_LEN = 15;
+ public static final int BUDGET_LEN = 24;
+ public static final int COLLECTIVITE_LIB_LEN = 250;
+ public static final int BUDGET_LIB_LEN = 250;
+ public static final int ERROR_MESSAGE_LEN = 2147483647;
+
+
+
+
+ /**
+ * MAPS IMPORT_ID column.
+ */
+ protected java.lang.String importId;
+ protected boolean isImportIdSet = false;
+ protected boolean isImportIdModified = false;
+
+
+
+
+ /**
+ * Default Constructor
+ */
+ public ImportVOPK() {
+ super();
+ }
+ /**
+ * Initializes PK with values in fields.
+ */
+ public ImportVOPK(java.lang.String importId) {
+ this();
+ setInnerImportId(importId);
+
+ }
+
+
+
+
+
+ public java.lang.String getImportId() { return importId; }
+ public void setImportId(java.lang.String importId) {
+ this.importId=importId;
+ this.isImportIdModified = true;
+ }
+ protected void setInnerImportId(java.lang.String importId) {
+ this.importId=importId;
+ this.isImportIdSet = true;
+ }
+ public java.lang.String getStrImportId(java.lang.String returnInCaseOfNull) {
+ return importId!=null ? importId.toString() : returnInCaseOfNull;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if(o instanceof ImportVOPK) {
+ boolean bRet = true;
+ ImportVOPK other = (ImportVOPK)o;
+
+
+ bRet = bRet && (getImportId().equals(other.getImportId()));
+
+ return bRet;
+ }
+ return false;
+ }
+ @Override
+ public int hashCode() {
+ int ret = 0;
+
+
+ ret += getImportId().hashCode();
+
+ return ret;
+ }
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.JdbcUtils;
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.PStmtBinder;
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.RowMapper;
+
+import java.util.List;
+
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Connection;
+
+
+public class ImportVOWrapper {
+
+ public static final String getSelectFieldsClause(String table) {
+ return ""+table+".UTI_LOGIN, "+table+".IMPORT_ID, "+table+".FILE_NAME, "+table+".FILE_TYPE, "+table+".SUBMIT_DATE, "+table+".END_DATE, "+table+".STATUS, "+table+".COLLECTIVITE, "+table+".BUDGET, "+table+".COLLECTIVITE_LIB, "+table+".BUDGET_LIB, "+table+".ERROR_MESSAGE";
+ }
+
+ public static final String getSelectFieldsClause() {
+ return "UTI_LOGIN, IMPORT_ID, FILE_NAME, FILE_TYPE, SUBMIT_DATE, END_DATE, STATUS, COLLECTIVITE, BUDGET, COLLECTIVITE_LIB, BUDGET_LIB, ERROR_MESSAGE";
+ }
+
+ public static ImportVOFull getImportVOFullBy(Connection con, Class clazz, String sql, PStmtBinder binder) throws SQLException {
+ return (ImportVOFull)JdbcUtils.queryObject(con, sql, new RowMapper.ClassRowMapper(clazz), binder);
+ }
+
+ public static List getAllImportVOFullBy(Connection con, Class clazz, String sql, PStmtBinder binder) throws SQLException {
+ return JdbcUtils.queryObjects(con, sql, new RowMapper.ClassRowMapper(clazz), binder);
+ }
+
+ public static List getAllImportVOFullBy(Connection con, Class clazz, String sql) throws SQLException {
+ return JdbcUtils.queryObjects(con, sql, new RowMapper.ClassRowMapper(clazz), null);
+ }
+
+ public static ImportVOFull getImportVOFullByPk(Connection con, ImportVOPK data) throws SQLException {
+ return getImportVOFullByPk(con, data, ImportVOFull.class);
+ }
+
+ public static ImportVOFull getImportVOFullByPk(Connection con, ImportVOPK data, Class clazz) throws SQLException {
+ String sql = "SELECT " + getSelectFieldsClause() + " FROM XEM_IMPORTS WHERE IMPORT_ID=?";
+ return getImportVOFullBy(con, clazz, sql, new PStmtBinder.SimplePStmtBinderBuilder().add(data.importId).toPStmtBinder());
+ }
+
+ public static void deleteImportVO(Connection con, ImportVOPK data) throws SQLException {
+ String sql = "DELETE FROM XEM_IMPORTS WHERE IMPORT_ID=?";
+ JdbcUtils.executeUpdate(con,sql,new PStmtBinder.SimplePStmtBinderBuilder().add(data.importId==null ? (java.lang.String)null : data.importId).toPStmtBinder());
+ }
+
+
+ public static void insertImportVO(Connection con, ImportVOFull data) throws SQLException {
+ int colCount=0;
+ StringBuilder sql = new StringBuilder("INSERT INTO XEM_IMPORTS(");
+
+
+ if(data.isUtiLoginSet | data.isUtiLoginModified) {
+ sql.append("UTI_LOGIN,");
+ colCount++;
+ }
+
+ if(data.isImportIdSet | data.isImportIdModified) {
+ sql.append("IMPORT_ID,");
+ colCount++;
+ }
+
+ if(data.isFileNameSet | data.isFileNameModified) {
+ sql.append("FILE_NAME,");
+ colCount++;
+ }
+
+ if(data.isFileTypeSet | data.isFileTypeModified) {
+ sql.append("FILE_TYPE,");
+ colCount++;
+ }
+
+ if(data.isSubmitDateSet | data.isSubmitDateModified) {
+ sql.append("SUBMIT_DATE,");
+ colCount++;
+ }
+
+ if(data.isEndDateSet | data.isEndDateModified) {
+ sql.append("END_DATE,");
+ colCount++;
+ }
+
+ if(data.isStatusSet | data.isStatusModified) {
+ sql.append("STATUS,");
+ colCount++;
+ }
+
+ if(data.isCollectiviteSet | data.isCollectiviteModified) {
+ sql.append("COLLECTIVITE,");
+ colCount++;
+ }
+
+ if(data.isBudgetSet | data.isBudgetModified) {
+ sql.append("BUDGET,");
+ colCount++;
+ }
+
+ if(data.isCollectiviteLibSet | data.isCollectiviteLibModified) {
+ sql.append("COLLECTIVITE_LIB,");
+ colCount++;
+ }
+
+ if(data.isBudgetLibSet | data.isBudgetLibModified) {
+ sql.append("BUDGET_LIB,");
+ colCount++;
+ }
+
+ if(data.isErrorMessageSet | data.isErrorMessageModified) {
+ sql.append("ERROR_MESSAGE,");
+ colCount++;
+ }
+ if(colCount==0) throw new SQLException("No data to insert");
+ sql.deleteCharAt(sql.length() - 1);
+ sql.append(") VALUES (");
+ for(int i=0;i<colCount;i++) sql.append("?,");
+ sql.deleteCharAt(sql.length() - 1);
+ sql.append(")");
+ PStmtBinder.SimplePStmtBinderBuilder builder = new PStmtBinder.SimplePStmtBinderBuilder();
+
+ if(data.isUtiLoginSet | data.isUtiLoginModified) {
+ if(data.utiLogin==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.utiLogin);
+ }
+
+ if(data.isImportIdSet | data.isImportIdModified) {
+ if(data.importId==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.importId);
+ }
+
+ if(data.isFileNameSet | data.isFileNameModified) {
+ if(data.fileName==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.fileName);
+ }
+
+ if(data.isFileTypeSet | data.isFileTypeModified) {
+ if(data.fileType==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.fileType);
+ }
+
+ if(data.isSubmitDateSet | data.isSubmitDateModified) {
+ if(data.submitDate==null) builder=builder.add((java.sql.Timestamp)null); else builder=builder.add(data.submitDate);
+ }
+
+ if(data.isEndDateSet | data.isEndDateModified) {
+ if(data.endDate==null) builder=builder.add((java.sql.Timestamp)null); else builder=builder.add(data.endDate);
+ }
+
+ if(data.isStatusSet | data.isStatusModified) {
+ if(data.status==null) builder=builder.add((java.lang.Integer)null); else builder=builder.add(data.status);
+ }
+
+ if(data.isCollectiviteSet | data.isCollectiviteModified) {
+ if(data.collectivite==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectivite);
+ }
+
+ if(data.isBudgetSet | data.isBudgetModified) {
+ if(data.budget==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budget);
+ }
+
+ if(data.isCollectiviteLibSet | data.isCollectiviteLibModified) {
+ if(data.collectiviteLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectiviteLib);
+ }
+
+ if(data.isBudgetLibSet | data.isBudgetLibModified) {
+ if(data.budgetLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budgetLib);
+ }
+
+ if(data.isErrorMessageSet | data.isErrorMessageModified) {
+ if(data.errorMessage==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.errorMessage);
+ }
+
+ JdbcUtils.executeUpdate(con,sql.toString(),builder.toPStmtBinder());
+ }
+
+ public static void updateImportVO(Connection con, ImportVOFull data) throws SQLException {
+ PreparedStatement ps = null;
+ StringBuilder sql=new StringBuilder("UPDATE XEM_IMPORTS SET ");
+ if(data.isUtiLoginModified) sql.append("UTI_LOGIN=?,");
+ if(data.isFileNameModified) sql.append("FILE_NAME=?,");
+ if(data.isFileTypeModified) sql.append("FILE_TYPE=?,");
+ if(data.isSubmitDateModified) sql.append("SUBMIT_DATE=?,");
+ if(data.isEndDateModified) sql.append("END_DATE=?,");
+ if(data.isStatusModified) sql.append("STATUS=?,");
+ if(data.isCollectiviteModified) sql.append("COLLECTIVITE=?,");
+ if(data.isBudgetModified) sql.append("BUDGET=?,");
+ if(data.isCollectiviteLibModified) sql.append("COLLECTIVITE_LIB=?,");
+ if(data.isBudgetLibModified) sql.append("BUDGET_LIB=?,");
+ if(data.isErrorMessageModified) sql.append("ERROR_MESSAGE=?,");
+
+ sql.deleteCharAt(sql.length()-1);
+ sql.append(" WHERE IMPORT_ID=?");
+ PStmtBinder.SimplePStmtBinderBuilder builder = new PStmtBinder.SimplePStmtBinderBuilder();
+
+ if(data.isUtiLoginModified) {
+ if(data.utiLogin==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.utiLogin);
+ }
+ if(data.isFileNameModified) {
+ if(data.fileName==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.fileName);
+ }
+ if(data.isFileTypeModified) {
+ if(data.fileType==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.fileType);
+ }
+ if(data.isSubmitDateModified) {
+ if(data.submitDate==null) builder=builder.add((java.sql.Timestamp)null); else builder=builder.add(data.submitDate);
+ }
+ if(data.isEndDateModified) {
+ if(data.endDate==null) builder=builder.add((java.sql.Timestamp)null); else builder=builder.add(data.endDate);
+ }
+ if(data.isStatusModified) {
+ if(data.status==null) builder=builder.add((java.lang.Integer)null); else builder=builder.add(data.status);
+ }
+ if(data.isCollectiviteModified) {
+ if(data.collectivite==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectivite);
+ }
+ if(data.isBudgetModified) {
+ if(data.budget==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budget);
+ }
+ if(data.isCollectiviteLibModified) {
+ if(data.collectiviteLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectiviteLib);
+ }
+ if(data.isBudgetLibModified) {
+ if(data.budgetLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budgetLib);
+ }
+ if(data.isErrorMessageModified) {
+ if(data.errorMessage==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.errorMessage);
+ }
+ builder=builder.add(data.importId);
+
+ JdbcUtils.executeUpdate(con,sql.toString(),builder.toPStmtBinder());
+ }
+
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+
+public interface VoConstants {
+ public final String NOT_NULL_MSG = "should not be null";
+ public final String TOO_LONG_MSG_PRFX = "null";
+ public final String TOO_LONG_MSG_SUFX = "is tooo long";
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+public class XemImportsFilesFL extends XemImportsFilesVOPK implements java.io.Serializable {
+
+ public static final transient String SELECT_REQ = "SELECT IMPORT_ID, SUB_FILE_NAME FROM XEM_IMPORTS_FILES ";
+
+ public XemImportsFilesFL() {
+ super();
+ }
+ public XemImportsFilesFL(ResultSet rs) throws SQLException {
+ this();
+ int i=1;
+ setInnerImportId(rs.getString(i++));
+ setInnerSubFileName(rs.getString(i++));
+
+ }
+
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+public class XemImportsFilesVOFull extends XemImportsFilesVOPK implements java.io.Serializable {
+
+
+
+ /**
+ * MAPS FILE_TYPE column.
+ */
+ protected java.lang.String fileType;
+ protected boolean isFileTypeSet = false;
+ protected boolean isFileTypeModified = false;
+
+
+
+ /**
+ * MAPS STATUS column.
+ */
+ protected java.lang.Integer status;
+ protected boolean isStatusSet = false;
+ protected boolean isStatusModified = false;
+
+
+
+ /**
+ * MAPS COLLECTIVITE column.
+ */
+ protected java.lang.String collectivite;
+ protected boolean isCollectiviteSet = false;
+ protected boolean isCollectiviteModified = false;
+
+
+
+ /**
+ * MAPS BUDGET column.
+ */
+ protected java.lang.String budget;
+ protected boolean isBudgetSet = false;
+ protected boolean isBudgetModified = false;
+
+
+
+ /**
+ * MAPS COLLECTIVITE_LIB column.
+ */
+ protected java.lang.String collectiviteLib;
+ protected boolean isCollectiviteLibSet = false;
+ protected boolean isCollectiviteLibModified = false;
+
+
+
+ /**
+ * MAPS BUDGET_LIB column.
+ */
+ protected java.lang.String budgetLib;
+ protected boolean isBudgetLibSet = false;
+ protected boolean isBudgetLibModified = false;
+
+
+
+ /**
+ * MAPS ERROR_MESSAGE column.
+ */
+ protected java.lang.String errorMessage;
+ protected boolean isErrorMessageSet = false;
+ protected boolean isErrorMessageModified = false;
+
+
+
+ /**
+ * Default Constructor
+ */
+ public XemImportsFilesVOFull() {
+ super();
+ }
+ /**
+ * Constructs a new Full object, initializing only PK fileds.
+ */
+ public XemImportsFilesVOFull(java.lang.String importId, java.lang.String subFileName) {
+ super(importId, subFileName);
+ }
+ public XemImportsFilesVOFull(ResultSet rs) throws SQLException {
+ this();
+ int i=1;
+ setInnerImportId(rs.getString(i++));
+ setInnerSubFileName(rs.getString(i++));
+ setInnerFileType(rs.getString(i++));
+ int statusTmp = rs.getInt(i++); if(!rs.wasNull()) setInnerStatus(new java.lang.Integer(statusTmp));
+ setInnerCollectivite(rs.getString(i++));
+ setInnerBudget(rs.getString(i++));
+ setInnerCollectiviteLib(rs.getString(i++));
+ setInnerBudgetLib(rs.getString(i++));
+ setInnerErrorMessage(rs.getString(i++));
+
+ }
+
+
+
+
+
+ public java.lang.String getFileType() { return fileType; }
+ public void setFileType(java.lang.String fileType) {
+ this.fileType=fileType;
+ this.isFileTypeModified = true;
+ }
+ protected void setInnerFileType(java.lang.String fileType) {
+ this.fileType=fileType;
+ this.isFileTypeSet = true;
+ }
+ public java.lang.String getStrFileType(java.lang.String returnInCaseOfNull) {
+ return fileType!=null ? fileType.toString() : returnInCaseOfNull;
+ }
+
+
+
+
+
+ public java.lang.Integer getStatus() { return status; }
+ public void setStatus(java.lang.Integer status) {
+ this.status=status;
+ this.isStatusModified = true;
+ }
+ protected void setInnerStatus(java.lang.Integer status) {
+ this.status=status;
+ this.isStatusSet = true;
+ }
+ public java.lang.String getStrStatus(java.lang.String returnInCaseOfNull) {
+ return status!=null ? status.toString() : returnInCaseOfNull;
+ }
+
+
+
+
+
+ public java.lang.String getCollectivite() { return collectivite; }
+ public void setCollectivite(java.lang.String collectivite) {
+ this.collectivite=collectivite;
+ this.isCollectiviteModified = true;
+ }
+ protected void setInnerCollectivite(java.lang.String collectivite) {
+ this.collectivite=collectivite;
+ this.isCollectiviteSet = true;
+ }
+ public java.lang.String getStrCollectivite(java.lang.String returnInCaseOfNull) {
+ return collectivite!=null ? collectivite.toString() : returnInCaseOfNull;
+ }
+
+
+
+
+
+ public java.lang.String getBudget() { return budget; }
+ public void setBudget(java.lang.String budget) {
+ this.budget=budget;
+ this.isBudgetModified = true;
+ }
+ protected void setInnerBudget(java.lang.String budget) {
+ this.budget=budget;
+ this.isBudgetSet = true;
+ }
+ public java.lang.String getStrBudget(java.lang.String returnInCaseOfNull) {
+ return budget!=null ? budget.toString() : returnInCaseOfNull;
+ }
+
+
+
+
+
+ public java.lang.String getCollectiviteLib() { return collectiviteLib; }
+ public void setCollectiviteLib(java.lang.String collectiviteLib) {
+ this.collectiviteLib=collectiviteLib;
+ this.isCollectiviteLibModified = true;
+ }
+ protected void setInnerCollectiviteLib(java.lang.String collectiviteLib) {
+ this.collectiviteLib=collectiviteLib;
+ this.isCollectiviteLibSet = true;
+ }
+ public java.lang.String getStrCollectiviteLib(java.lang.String returnInCaseOfNull) {
+ return collectiviteLib!=null ? collectiviteLib.toString() : returnInCaseOfNull;
+ }
+
+
+
+
+
+ public java.lang.String getBudgetLib() { return budgetLib; }
+ public void setBudgetLib(java.lang.String budgetLib) {
+ this.budgetLib=budgetLib;
+ this.isBudgetLibModified = true;
+ }
+ protected void setInnerBudgetLib(java.lang.String budgetLib) {
+ this.budgetLib=budgetLib;
+ this.isBudgetLibSet = true;
+ }
+ public java.lang.String getStrBudgetLib(java.lang.String returnInCaseOfNull) {
+ return budgetLib!=null ? budgetLib.toString() : returnInCaseOfNull;
+ }
+
+
+
+
+
+ public java.lang.String getErrorMessage() { return errorMessage; }
+ public void setErrorMessage(java.lang.String errorMessage) {
+ this.errorMessage=errorMessage;
+ this.isErrorMessageModified = true;
+ }
+ protected void setInnerErrorMessage(java.lang.String errorMessage) {
+ this.errorMessage=errorMessage;
+ this.isErrorMessageSet = true;
+ }
+ public java.lang.String getStrErrorMessage(java.lang.String returnInCaseOfNull) {
+ return errorMessage!=null ? errorMessage.toString() : returnInCaseOfNull;
+ }
+
+
+ public void validate() throws IllegalStateException {
+
+ if(importId==null) throw new IllegalStateException("IMPORT_ID "+VoConstants.NOT_NULL_MSG);
+
+ if(importId!=null &&importId.length()>IMPORT_ID_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"IMPORT_ID"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+ if(subFileName==null) throw new IllegalStateException("SUB_FILE_NAME "+VoConstants.NOT_NULL_MSG);
+
+ if(subFileName!=null &&subFileName.length()>SUB_FILE_NAME_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"SUB_FILE_NAME"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+ if(fileType==null) throw new IllegalStateException("FILE_TYPE "+VoConstants.NOT_NULL_MSG);
+
+ if(fileType!=null &&fileType.length()>FILE_TYPE_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"FILE_TYPE"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+
+
+
+
+ if(collectivite!=null &&collectivite.length()>COLLECTIVITE_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"COLLECTIVITE"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+
+ if(budget!=null &&budget.length()>BUDGET_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"BUDGET"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+
+ if(collectiviteLib!=null &&collectiviteLib.length()>COLLECTIVITE_LIB_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"COLLECTIVITE_LIB"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+
+ if(budgetLib!=null &&budgetLib.length()>BUDGET_LIB_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"BUDGET_LIB"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+
+ if(errorMessage!=null &&errorMessage.length()>ERROR_MESSAGE_LEN) throw new IllegalStateException(VoConstants.TOO_LONG_MSG_PRFX+"ERROR_MESSAGE"+VoConstants.TOO_LONG_MSG_SUFX);
+
+
+ }
+
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+
+public class XemImportsFilesVOPK implements java.io.Serializable {
+
+ public static final int IMPORT_ID_LEN = 200;
+ public static final int SUB_FILE_NAME_LEN = 2147483647;
+ public static final int FILE_TYPE_LEN = 200;
+ public static final int STATUS_LEN = 10;
+ public static final int COLLECTIVITE_LEN = 15;
+ public static final int BUDGET_LEN = 24;
+ public static final int COLLECTIVITE_LIB_LEN = 250;
+ public static final int BUDGET_LIB_LEN = 250;
+ public static final int ERROR_MESSAGE_LEN = 2147483647;
+
+
+
+
+ /**
+ * MAPS IMPORT_ID column.
+ */
+ protected java.lang.String importId;
+ protected boolean isImportIdSet = false;
+ protected boolean isImportIdModified = false;
+
+
+
+
+
+ /**
+ * MAPS SUB_FILE_NAME column.
+ */
+ protected java.lang.String subFileName;
+ protected boolean isSubFileNameSet = false;
+ protected boolean isSubFileNameModified = false;
+
+
+
+
+ /**
+ * Default Constructor
+ */
+ public XemImportsFilesVOPK() {
+ super();
+ }
+ /**
+ * Initializes PK with values in fields.
+ */
+ public XemImportsFilesVOPK(java.lang.String importId, java.lang.String subFileName) {
+ this();
+ setInnerImportId(importId);
+ setInnerSubFileName(subFileName);
+
+ }
+
+
+
+
+
+ public java.lang.String getImportId() { return importId; }
+ public void setImportId(java.lang.String importId) {
+ this.importId=importId;
+ this.isImportIdModified = true;
+ }
+ protected void setInnerImportId(java.lang.String importId) {
+ this.importId=importId;
+ this.isImportIdSet = true;
+ }
+ public java.lang.String getStrImportId(java.lang.String returnInCaseOfNull) {
+ return importId!=null ? importId.toString() : returnInCaseOfNull;
+ }
+
+
+
+
+
+ public java.lang.String getSubFileName() { return subFileName; }
+ public void setSubFileName(java.lang.String subFileName) {
+ this.subFileName=subFileName;
+ this.isSubFileNameModified = true;
+ }
+ protected void setInnerSubFileName(java.lang.String subFileName) {
+ this.subFileName=subFileName;
+ this.isSubFileNameSet = true;
+ }
+ public java.lang.String getStrSubFileName(java.lang.String returnInCaseOfNull) {
+ return subFileName!=null ? subFileName.toString() : returnInCaseOfNull;
+ }
+
+
+ public boolean equals(Object o) {
+ if(o instanceof XemImportsFilesVOPK) {
+ boolean bRet = true;
+ XemImportsFilesVOPK other = (XemImportsFilesVOPK)o;
+
+
+ bRet = bRet && (getImportId().equals(other.getImportId()));
+
+
+ bRet = bRet && (getSubFileName().equals(other.getSubFileName()));
+
+ return bRet;
+ }
+ return false;
+ }
+ public int hashCode() {
+ int ret = 0;
+
+
+ ret += getImportId().hashCode();
+
+
+ ret += getSubFileName().hashCode();
+
+ return ret;
+ }
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.dgfip.xemelios.batch.imports.utils;
+
+
+
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.JdbcUtils;
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.PStmtBinder;
+import fr.gouv.finances.dgfip.xemelios.data.utils.jdbc.RowMapper;
+import java.util.List;
+
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Connection;
+
+
+public class XemImportsFilesVOWrapper {
+
+ public static final String getSelectFieldsClause(String table) {
+ return ""+table+".IMPORT_ID, "+table+".SUB_FILE_NAME, "+table+".FILE_TYPE, "+table+".STATUS, "+table+".COLLECTIVITE, "+table+".BUDGET, "+table+".COLLECTIVITE_LIB, "+table+".BUDGET_LIB, "+table+".ERROR_MESSAGE";
+ }
+
+ public static final String getSelectFieldsClause() {
+ return "IMPORT_ID, SUB_FILE_NAME, FILE_TYPE, STATUS, COLLECTIVITE, BUDGET, COLLECTIVITE_LIB, BUDGET_LIB, ERROR_MESSAGE";
+ }
+
+ public static XemImportsFilesVOFull getXemImportsFilesVOFullBy(Connection con, Class clazz, String sql, PStmtBinder binder) throws SQLException {
+ return (XemImportsFilesVOFull)JdbcUtils.queryObject(con, sql, new RowMapper.ClassRowMapper(clazz), binder);
+ }
+
+ public static List getAllXemImportsFilesVOFullBy(Connection con, Class clazz, String sql, PStmtBinder binder) throws SQLException {
+ return JdbcUtils.queryObjects(con, sql, new RowMapper.ClassRowMapper(clazz), binder);
+ }
+
+ public static List getAllXemImportsFilesVOFullBy(Connection con, Class clazz, String sql) throws SQLException {
+ return JdbcUtils.queryObjects(con, sql, new RowMapper.ClassRowMapper(clazz), null);
+ }
+
+ public static XemImportsFilesVOFull getXemImportsFilesVOFullByPk(Connection con, XemImportsFilesVOPK data) throws SQLException {
+ return getXemImportsFilesVOFullByPk(con, data, XemImportsFilesVOFull.class);
+ }
+
+ public static XemImportsFilesVOFull getXemImportsFilesVOFullByPk(Connection con, XemImportsFilesVOPK data, Class clazz) throws SQLException {
+ String sql = "SELECT " + getSelectFieldsClause() + " FROM XEM_IMPORTS_FILES WHERE IMPORT_ID=? AND SUB_FILE_NAME=?";
+ return getXemImportsFilesVOFullBy(con, clazz, sql, new PStmtBinder.SimplePStmtBinderBuilder().add(data.importId).add(data.subFileName).toPStmtBinder());
+ }
+
+ public static void deleteXemImportsFilesVO(Connection con, XemImportsFilesVOPK data) throws SQLException {
+ String sql = "DELETE FROM XEM_IMPORTS_FILES WHERE IMPORT_ID=? AND SUB_FILE_NAME=?";
+ JdbcUtils.executeUpdate(con,sql,new PStmtBinder.SimplePStmtBinderBuilder().add(data.importId==null ? (java.lang.String)null : data.importId).add(data.subFileName==null ? (java.lang.String)null : data.subFileName).toPStmtBinder());
+ }
+
+
+ public static void insertXemImportsFilesVO(Connection con, XemImportsFilesVOFull data) throws SQLException {
+ int colCount=0;
+ StringBuilder sql = new StringBuilder("INSERT INTO XEM_IMPORTS_FILES(");
+
+
+ if(data.isImportIdSet | data.isImportIdModified) {
+ sql.append("IMPORT_ID,");
+ colCount++;
+ }
+
+ if(data.isSubFileNameSet | data.isSubFileNameModified) {
+ sql.append("SUB_FILE_NAME,");
+ colCount++;
+ }
+
+ if(data.isFileTypeSet | data.isFileTypeModified) {
+ sql.append("FILE_TYPE,");
+ colCount++;
+ }
+
+ if(data.isStatusSet | data.isStatusModified) {
+ sql.append("STATUS,");
+ colCount++;
+ }
+
+ if(data.isCollectiviteSet | data.isCollectiviteModified) {
+ sql.append("COLLECTIVITE,");
+ colCount++;
+ }
+
+ if(data.isBudgetSet | data.isBudgetModified) {
+ sql.append("BUDGET,");
+ colCount++;
+ }
+
+ if(data.isCollectiviteLibSet | data.isCollectiviteLibModified) {
+ sql.append("COLLECTIVITE_LIB,");
+ colCount++;
+ }
+
+ if(data.isBudgetLibSet | data.isBudgetLibModified) {
+ sql.append("BUDGET_LIB,");
+ colCount++;
+ }
+
+ if(data.isErrorMessageSet | data.isErrorMessageModified) {
+ sql.append("ERROR_MESSAGE,");
+ colCount++;
+ }
+ if(colCount==0) throw new SQLException("No data to insert");
+ sql.deleteCharAt(sql.length() - 1);
+ sql.append(") VALUES (");
+ for(int i=0;i<colCount;i++) sql.append("?,");
+ sql.deleteCharAt(sql.length() - 1);
+ sql.append(")");
+ PStmtBinder.SimplePStmtBinderBuilder builder = new PStmtBinder.SimplePStmtBinderBuilder();
+
+ if(data.isImportIdSet | data.isImportIdModified) {
+
+ if(data.importId==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.importId);
+
+
+ }
+
+ if(data.isSubFileNameSet | data.isSubFileNameModified) {
+
+ if(data.subFileName==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.subFileName);
+
+
+ }
+
+ if(data.isFileTypeSet | data.isFileTypeModified) {
+
+ if(data.fileType==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.fileType);
+
+
+ }
+
+ if(data.isStatusSet | data.isStatusModified) {
+
+ if(data.status==null) builder=builder.add((java.lang.Integer)null); else builder=builder.add(data.status);
+
+
+ }
+
+ if(data.isCollectiviteSet | data.isCollectiviteModified) {
+
+ if(data.collectivite==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectivite);
+
+
+ }
+
+ if(data.isBudgetSet | data.isBudgetModified) {
+
+ if(data.budget==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budget);
+
+
+ }
+
+ if(data.isCollectiviteLibSet | data.isCollectiviteLibModified) {
+
+ if(data.collectiviteLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectiviteLib);
+
+
+ }
+
+ if(data.isBudgetLibSet | data.isBudgetLibModified) {
+
+ if(data.budgetLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budgetLib);
+
+
+ }
+
+ if(data.isErrorMessageSet | data.isErrorMessageModified) {
+
+ if(data.errorMessage==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.errorMessage);
+
+
+ }
+
+
+ JdbcUtils.executeUpdate(con,sql.toString(),builder.toPStmtBinder());
+
+
+
+ }
+
+ public static void updateXemImportsFilesVO(Connection con, XemImportsFilesVOFull data) throws SQLException {
+ PreparedStatement ps = null;
+ StringBuilder sql=new StringBuilder("UPDATE XEM_IMPORTS_FILES SET ");
+ if(data.isFileTypeModified) sql.append("FILE_TYPE=?,");
+ if(data.isStatusModified) sql.append("STATUS=?,");
+ if(data.isCollectiviteModified) sql.append("COLLECTIVITE=?,");
+ if(data.isBudgetModified) sql.append("BUDGET=?,");
+ if(data.isCollectiviteLibModified) sql.append("COLLECTIVITE_LIB=?,");
+ if(data.isBudgetLibModified) sql.append("BUDGET_LIB=?,");
+ if(data.isErrorMessageModified) sql.append("ERROR_MESSAGE=?,");
+
+ sql.deleteCharAt(sql.length()-1);
+ sql.append(" WHERE IMPORT_ID=? AND SUB_FILE_NAME=?");
+ PStmtBinder.SimplePStmtBinderBuilder builder = new PStmtBinder.SimplePStmtBinderBuilder();
+
+ if(data.isFileTypeModified) {
+
+ if(data.fileType==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.fileType);
+
+
+ }
+ if(data.isStatusModified) {
+
+ if(data.status==null) builder=builder.add((java.lang.Integer)null); else builder=builder.add(data.status);
+
+
+ }
+ if(data.isCollectiviteModified) {
+
+ if(data.collectivite==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectivite);
+
+
+ }
+ if(data.isBudgetModified) {
+
+ if(data.budget==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budget);
+
+
+ }
+ if(data.isCollectiviteLibModified) {
+
+ if(data.collectiviteLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.collectiviteLib);
+
+
+ }
+ if(data.isBudgetLibModified) {
+
+ if(data.budgetLib==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.budgetLib);
+
+
+ }
+ if(data.isErrorMessageModified) {
+
+ if(data.errorMessage==null) builder=builder.add((java.lang.String)null); else builder=builder.add(data.errorMessage);
+
+
+ }
+
+ builder=builder.add(data.importId);
+
+ builder=builder.add(data.subFileName);
+
+ JdbcUtils.executeUpdate(con,sql.toString(),builder.toPStmtBinder());
+ }
+
+
+
+
+ public static List<XemImportsFilesFL> getChildren(Connection con, String request, Class clazz, PStmtBinder binder) throws SQLException {
+ return (List<XemImportsFilesFL>)JdbcUtils.queryObjects(con,request, new RowMapper.ClassRowMapper(clazz), binder);
+ }
+
+}
+
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2010 axYus - http://www.axyus.com
+ * 2010 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS_NB.
+ *
+ * XEMELIOS_NB is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS_NB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS_NB; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.pdf;
+
+import org.apache.log4j.Logger;
+import org.xhtmlrenderer.pdf.ITextOutputDevice;
+import org.xhtmlrenderer.pdf.ITextUserAgent;
+
+/**
+ *
+ * @author cmarchand
+ */
+public class BatchUserAgentCallback extends ITextUserAgent {
+ private static final Logger logger = Logger.getLogger(BatchUserAgentCallback.class);
+
+ public BatchUserAgentCallback(ITextOutputDevice device) {
+ super(device);
+ }
+
+ @Override
+ public String resolveURI(String uri) {
+// logger.debug("trying to resolve uri: "+uri);
+ return super.resolveURI(uri);
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2010 axYus - http://www.axyus.com
+ * 2010 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS_NB.
+ *
+ * XEMELIOS_NB is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS_NB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS_NB; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.pdf;
+
+import fr.gouv.finances.cp.xemelios.data.impl.MySqlDataLayer;
+import fr.gouv.finances.dgfip.xemelios.auth.XemeliosUser;
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.batch.BatchRunner;
+import fr.gouv.finances.dgfip.xemelios.common.config.DocumentModel;
+import fr.gouv.finances.dgfip.xemelios.common.config.EtatModel;
+import fr.gouv.finances.dgfip.xemelios.data.DataImpl;
+import fr.gouv.finances.dgfip.xemelios.data.DataLayerManager;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author cmarchand
+ */
+public class PdfCreator extends Batch {
+ private static final Logger logger = Logger.getLogger(PdfCreator.class);
+ public static final String PROP_DOCUMENTS_DEF_DIR = "documents-def.dir";
+// public static final String PROP_DATALAYER_NAME = "datalayer.name";
+ public static final String PROP_DOCUMENT_ID = "document.id";
+ public static final Integer STATUS_NONE = null;
+ public static final Integer STATUS_IDLE = 0;
+ public static final Integer STATUS_RUNNING = 1;
+ public static final Integer STATUS_TERMINATED = 2;
+ public static final Integer STATUS_ERROR = 3;
+
+ private static ExecutorService runner = Executors.newFixedThreadPool(3);
+
+ private String documentId;
+
+ public PdfCreator(String args[]) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ documentId = getProps().getProperty(PROP_DOCUMENT_ID);
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ logger.debug("running PdfCreator for document "+documentId);
+ XemeliosUser user = new User();
+ Connection con = null;
+ try {
+ EtatModel em = BatchRunner.getInstance().getDocuments().getDocumentById("cg-etat").getEtatById("BalanceGenerale");
+ con = PoolManager.getInstance().getConnection();
+ DataImpl impl = DataLayerManager.getImplementation();
+ if(impl instanceof MySqlDataLayer) {
+ MySqlDataLayer msImpl = (MySqlDataLayer)impl;
+ if("compteGestionEtat".equals(documentId)) {
+ String select = "SELECT COLLECTIVITE, BUDGET, EXERCICE FROM PDF_CREATION WHERE DOCUMENT_ID=? AND ETAT_ID=? AND CREATION_STATUS IS NULL";
+ PreparedStatement ps = con.prepareStatement(select);
+ ps.setString(1,documentId);
+ ps.setString(2,"BalanceGenerale");
+ ResultSet rs = ps.executeQuery();
+ while(rs.next()) {
+ String collectivite = rs.getString(1);
+ String budget = rs.getString(2);
+ int exercice = rs.getInt(3);
+ PdfCreatorImpl process = new PdfCreatorImpl(documentId, "BalanceGenerale", collectivite, budget, exercice, user, msImpl, em);
+ runner.submit(process);
+ }
+
+ }
+ } else {
+ throw new RuntimeException("PdfCreator only runs with MysqlDataLayer");
+ }
+ } catch(Exception ex) {
+ logger.error("in doProcess",ex);
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ con = null;
+ }
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "pdf.creator";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return getResumeTraitement()+"<"+documentId+">";
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+// sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+// for(RunnableBatch rb: pool.getThreads()) {
+// sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+// if(rb.isAlive()) sb.append(rb.getInformations());
+// }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+ private class User implements XemeliosUser {
+ @Override
+ public String getId() {
+ return "PdfCreatorUser";
+ }
+ @Override
+ public String getDisplayName() {
+ return getId();
+ }
+ @Override
+ public boolean hasRole(String role) {
+ return true;
+ }
+ @Override
+ public boolean hasDocument(String document) {
+ return true;
+ }
+ @Override
+ public boolean hasCollectivite(String collectivite, DocumentModel dm) {
+ return true;
+ }
+ }
+
+ protected class PdfCreatorImpl extends RunnableBatch {
+ private String documentId;
+ private String etatId;
+ private String collectivite;
+ private String budget;
+ private int exercice;
+ private XemeliosUser user;
+ private MySqlDataLayer msLayer;
+ private EtatModel em;
+
+ public PdfCreatorImpl(String documentId, String etatId, String collectivite, String budget, int exercice, XemeliosUser user, MySqlDataLayer msLayer, EtatModel em) {
+ super();
+ this.documentId=documentId;
+ this.etatId=etatId;
+ this.collectivite=collectivite;
+ this.budget=budget;
+ this.exercice=exercice;
+ this.msLayer = msLayer;
+ this.user=user;
+ this.em=em;
+ }
+
+ @Override
+ public void run() {
+ logger.info("starting "+documentId+"."+etatId+" "+collectivite+" "+budget+" "+exercice);
+ super.run();
+ if("compteGestionEtat".equals(documentId) && "BalanceGenerale".equals(etatId)) {
+ generateCgEtatBalance();
+ } else {
+ getNotifier().notifyThreadStop(this);
+ throw new RuntimeException("PdfCreator do not know how to PDF's "+documentId);
+ }
+ getNotifier().notifyThreadStop(this);
+ }
+
+ protected void generateCgEtatBalance() {
+ PdfCreatorCgEtatBalance generator = new PdfCreatorCgEtatBalance(em,collectivite, budget, exercice,user);
+ generator.run();
+ }
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\t").append(getName()).append(":");
+ if(isAlive()) {
+ sb.append("PdfCreator<"+documentId+"> running.");
+ } else {
+ if(isStarted()) {
+ sb.append("PdfCreator<"+documentId+"> fully terminated.");
+ } else {
+ sb.append("PdfCreator<"+documentId+"> idle");
+ }
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2010 axYus - http://www.axyus.com
+ * 2010 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS_NB.
+ *
+ * XEMELIOS_NB is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS_NB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS_NB; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.pdf;
+
+import fr.gouv.finances.dgfip.utils.IoUtils;
+import fr.gouv.finances.dgfip.utils.Pair;
+import fr.gouv.finances.dgfip.utils.xml.FactoryProvider;
+import fr.gouv.finances.dgfip.utils.xml.transform.CustomURIResolver;
+import fr.gouv.finances.dgfip.xemelios.auth.XemeliosUser;
+import fr.gouv.finances.dgfip.xemelios.batch.BatchRunner;
+import fr.gouv.finances.dgfip.xemelios.common.PJRef;
+import fr.gouv.finances.dgfip.xemelios.common.config.EtatModel;
+import fr.gouv.finances.dgfip.xemelios.data.DataLayerManager;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import fr.gouv.finances.dgfip.xemelios.utils.FileUtils;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.util.ArrayList;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xhtmlrenderer.context.StyleReference;
+import org.xhtmlrenderer.pdf.ITextRenderer;
+
+/**
+ *
+ * @author cmarchand
+ */
+public class PdfCreatorCgEtatBalance {
+ private EtatModel em;
+ private String collectivite;
+ private String budget;
+ private int exercice;
+ private Pair pColl, pBudg;
+ private XemeliosUser user;
+ private Logger logger = null;
+ XPathFactory xpf = FactoryProvider.getXPathFactory();
+
+ public PdfCreatorCgEtatBalance(EtatModel em, String collectivite, String budget, int exercice, XemeliosUser user) {
+ super();
+ this.em=em;
+ this.collectivite=collectivite;
+ this.budget=budget;
+ this.exercice=exercice;
+ this.pColl=new Pair(collectivite, collectivite);
+ this.pBudg = new Pair(budget, budget);
+ this.user=user;
+ logger = Logger.getLogger(PdfCreatorCgEtatBalance.class.getName()+"<"+collectivite+","+budget+","+exercice+">");
+ }
+
+ public void run() {
+ if(flagRowStart(null)!=1) {
+ logger.warn("cancelling "+collectivite+"-"+budget+"-"+exercice);
+ return;
+ }
+ String xpath=em.getImportableElement().getPath().getPath()+"[n:Pied/@NumPage='1']";
+ XPath xp = xpf.newXPath();
+ xp.setNamespaceContext(em.getParent().getNamespaces());
+ try {
+ ArrayList<String> documents = DataLayerManager.getImplementation().getDocumentListFromXPath(em.getImportableElement(), collectivite, budget, Integer.toString(exercice), null, null, xpath, user);
+ if(documents.size()==1) {
+ Document dom = DataLayerManager.getImplementation().getDocumentAsDom(em, pColl, pBudg, documents.get(0), user);
+ String firstPage = "1";
+ String lastPage=null;
+ // on va chercher les numéros de page
+ Element ligneSommaire = (Element)xp.evaluate("/n:CompteGestionEtat/n:Entete/n:Infos/n:Sommaire/n:LigneSommaire[1]", dom, XPathConstants.NODE);
+ if(ligneSommaire!=null) {
+ firstPage = ligneSommaire.getAttribute("FirstPage");
+ lastPage = ligneSommaire.getAttribute("LastPage");
+ } else {
+ lastPage = xp.evaluate("/n:CompteGestionEtat/n:BalanceGenerale/n:PageBalanceGenerale/@added:LastPage", dom);
+ }
+ int first = Integer.parseInt(firstPage);
+ int last = Integer.parseInt(lastPage);
+ ITextRenderer renderer = new ITextRenderer();
+ BatchUserAgentCallback callback = new BatchUserAgentCallback(renderer.getOutputDevice());
+ callback.setSharedContext(renderer.getSharedContext());
+ renderer.getSharedContext().setUserAgentCallback(callback);
+ StyleReference css = new StyleReference(callback);
+ renderer.getSharedContext().setCss(css);
+ File xslFile = new File(new File(new File(System.getProperty("user.home")),"xemelios/documents-def-ovrrd"),em.getXslt());
+ if(!xslFile.exists()) xslFile = new File(new File(em.getParent().getBaseDirectory()),em.getXslt());
+ InputStream is = IoUtils.getInputStream(xslFile.getPath());
+
+ File tmp = File.createTempFile("CGE_Bal_"+collectivite+"_"+budget+"_"+exercice, ".pdf", FileUtils.getTempDir());
+
+ OutputStream output = new FileOutputStream(tmp);
+ TransformerFactory tFactory = FactoryProvider.getTransformerFactory();
+ tFactory.setURIResolver(new CustomURIResolver(tFactory.getURIResolver(),xslFile.getParentFile().toURI().toURL().toExternalForm()));
+ Transformer tr = tFactory.newTransformer(new StreamSource(is));
+ tr.setParameter("browser-destination", em.useExternalBrowser() ? "external" : "internal");
+ // on passe la nomenclature en parametre
+ // on recupere l'ID de la nomenclature
+ String idRepository = null;
+ if (em.getParent().getReferenceNomenclaturePath() != null && em.getParent().getReferenceNomenclaturePath().getCodePath() != null) {
+ idRepository = (String) xp.evaluate(em.getParent().getReferenceNomenclaturePath().getCodePath().getPath(), dom.getDocumentElement(), XPathConstants.STRING);
+ }
+ if (idRepository != null && idRepository.length() == 0) {
+ idRepository = null;
+ }
+ Document repository = DataLayerManager.getImplementation().getRepositoryAsDom(em.getParent(), pColl, idRepository, user);
+ if (repository != null) {
+ tr.setParameter("repository", repository);
+ }
+ // on passe la config
+ tr.setParameter("config", BatchRunner.getInstance().getDocuments().getSmallDOM());
+ tr.setParameter("collectivite", pColl.key);
+ tr.setParameter("budget", budget);
+
+ boolean isFirstPage = true;
+ for(int i=first; i<=last; i++) {
+ xpath=em.getImportableElement().getPath().getPath()+"[n:Pied/@NumPage='"+i+"']";
+ documents = DataLayerManager.getImplementation().getDocumentListFromXPath(em.getImportableElement(), collectivite, budget, Integer.toString(exercice), null, null, xpath, user);
+ Document doc = DataLayerManager.getImplementation().getDocumentAsDom(em, pColl, pBudg, documents.get(0), user);
+ DOMResult result = new DOMResult();
+ tr.transform(new DOMSource(doc), result);
+ Document xhtml = (Document) result.getNode();
+ renderer.setDocument(xhtml, "doc.xhtml");
+ renderer.layout();
+ if (isFirstPage) {
+ renderer.createPDF(output, false);
+ isFirstPage = false;
+ } else {
+ renderer.writeNextDocument();
+ }
+ }
+ renderer.finishPDF();
+ output.flush(); output.close();
+
+ // attachement de la PJ
+ PJRef pjRef = new PJRef();
+ pjRef.setCollectivite(collectivite);
+ pjRef.setFileName("CompteGestionEtat-BalanceGenerale-"+collectivite+"-"+budget+"-"+exercice+".pdf");
+ pjRef.setPjName(pjRef.getFileName());
+ FileInputStream fis = new FileInputStream(tmp);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[2048];
+ int read = fis.read(buffer);
+ do {
+ baos.write(buffer, 0, read);
+ read = fis.read(buffer);
+ } while(read > 0);
+ fis.close();
+ pjRef.setData(baos.toByteArray());
+ DataLayerManager.getImplementation().importPj(pjRef, null, user);
+ tmp.delete();
+ flagRowSuccess(1);
+ } else {
+ logger.error("ai trouvé "+documents.size()+" page 1");
+ }
+ } catch(Exception ex) {
+ flagRowError(-1);
+ logger.error("",ex);
+ }
+ }
+
+ protected int flagRowStart(Integer value) {
+ return flagRow(1, value);
+ }
+ protected int flagRowError(Integer value) {
+ return flagRow(2,value);
+ }
+ protected int flagRowSuccess(Integer value) {
+ return flagRow(3, value);
+ }
+ protected int flagRow(int status, Integer value) {
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String sql = "UPDATE PDF_CREATION SET CREATION_STATUS=? WHERE DOCUMENT_ID='compteGestionEtat' AND ETAT_ID='BalanceGenerale' AND COLLECTIVITE=? AND BUDGET=? AND EXERCICE=?";
+ if(value==null) sql = sql.concat(" AND CREATION_STATUS IS NULL");
+ else if(value!= -1) sql = sql.concat(" AND CREATION_STATUS=?");
+logger.info(status+"/"+value+" : "+sql);
+ PreparedStatement ps = con.prepareStatement(sql);
+ ps.setInt(1,status);
+ ps.setString(2, collectivite);
+ ps.setString(3, budget);
+ ps.setInt(4, exercice);
+ if(value!=null && value!= -1) ps.setInt(5,value.intValue());
+ return ps.executeUpdate();
+ } catch(Exception ex) {
+ logger.error("flagRow",ex);
+ return 0;
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ con = null;
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2010 axYus - http://www.axyus.com
+ * 2010 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS_NB.
+ *
+ * XEMELIOS_NB is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS_NB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS_NB; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.dgfip.xemelios.batch.pdf;
+
+import fr.gouv.finances.cp.xemelios.data.impl.MySqlDataLayer;
+import fr.gouv.finances.dgfip.xemelios.auth.XemeliosUser;
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.batch.BatchRunner;
+import fr.gouv.finances.dgfip.xemelios.common.config.DocumentModel;
+import fr.gouv.finances.dgfip.xemelios.data.DataImpl;
+import fr.gouv.finances.dgfip.xemelios.data.DataLayerManager;
+import fr.gouv.finances.dgfip.xemelios.data.impl.pool.PoolManager;
+import fr.gouv.finances.dgfip.xemelios.data.impl.sqlconfig.TDocument;
+import fr.gouv.finances.dgfip.xemelios.data.impl.sqlconfig.TEtat;
+import fr.gouv.finances.dgfip.xemelios.data.impl.sqlconfig.TPersistenceConfig;
+import fr.gouv.finances.dgfip.xemelios.data.impl.sqlconfig.TTable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author cmarchand
+ */
+public class PdfPreparator extends Batch {
+ private static final Logger logger = Logger.getLogger(PdfPreparator.class);
+ public static final String PROP_MAX_CONCURRENT_THREADS = "max.concurrent.threads";
+ public static final String PROP_DOCUMENTS_DEF_DIR = "documents-def.dir";
+ public static final String PROP_DATALAYER_NAME = "datalayer.name";
+ public static final String PROP_DOCUMENT_ID = "documents";
+ public static final Integer STATUS_NONE = null;
+ public static final Integer STATUS_IDLE = 0;
+ public static final Integer STATUS_RUNNING = 1;
+ public static final Integer STATUS_TERMINATED = 2;
+ public static final Integer STATUS_ERROR = 3;
+
+ private int maxConcurrentThreads = 1;
+
+ private String documents;
+
+ private static boolean initialized = false;
+
+ private ThreadPool<PdfPreparatorImpl> pool = null;
+
+ public PdfPreparator(String args[]) {
+ super(args);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ super.initialize();
+ String sTmp = getProps().getProperty(PROP_MAX_CONCURRENT_THREADS);
+ if(sTmp!=null && sTmp.length()>0) {
+ try {
+ maxConcurrentThreads = Integer.parseInt(sTmp);
+ } catch(Throwable t) {}
+ }
+ documents = getProps().getProperty(PROP_DOCUMENT_ID);
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ logger.debug("running PdfPreparator for document "+documents);
+ XemeliosUser user = new User();
+ ArrayList<PdfPreparatorImpl> threads = new ArrayList<PdfPreparatorImpl>();
+ try {
+ DataImpl impl = DataLayerManager.getImplementation();
+ if(impl instanceof MySqlDataLayer) {
+ MySqlDataLayer msImpl = (MySqlDataLayer)impl;
+ StringTokenizer st = new StringTokenizer(documents, ",");
+ while(st.hasMoreTokens()) {
+ PdfPreparatorImpl process = new PdfPreparatorImpl(st.nextToken(), user, msImpl);
+ threads.add(process);
+ }
+ pool = new ThreadPool<PdfPreparatorImpl>(threads);
+ logger.debug("starting pool with "+maxConcurrentThreads+" max concurrent threads");
+ pool.start(maxConcurrentThreads);
+ } else {
+ throw new RuntimeException("PdfCreator only runs with MysqlDataLayer");
+ }
+ } catch(Exception ex) {
+ logger.error("in doProcess",ex);
+ }
+ pool = new ThreadPool<PdfPreparatorImpl>(threads);
+ logger.debug("starting pool with "+maxConcurrentThreads+" max concurrent threads");
+ pool.start(maxConcurrentThreads);
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "pdf.preparator";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return getResumeTraitement();
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ if(isStarted()) {
+ sb.append(typeTraitementRefCode()).append(" - ").append(pool.getRunningThreadCount()).append(" running thread(s)\n");
+ for(RunnableBatch rb: pool.getThreads()) {
+ sb.append("\t").append(rb.getName()).append(": ").append(rb.isAlive()?"running":"idle").append("\n");
+ if(rb.isAlive()) sb.append(rb.getInformations());
+ }
+ } else {
+ sb.append(typeTraitementRefCode()).append(" - not started\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0";
+ }
+
+ private class User implements XemeliosUser {
+ @Override
+ public String getId() {
+ return "PdfPreparatorUser";
+ }
+ @Override
+ public String getDisplayName() {
+ return getId();
+ }
+ @Override
+ public boolean hasRole(String role) {
+ return true;
+ }
+ @Override
+ public boolean hasDocument(String document) {
+ return true;
+ }
+ @Override
+ public boolean hasCollectivite(String collectivite, DocumentModel dm) {
+ return true;
+ }
+ }
+
+ protected class PdfPreparatorImpl extends RunnableBatch {
+ private String documentId;
+ private XemeliosUser user;
+ private MySqlDataLayer msLayer;
+
+ public PdfPreparatorImpl(String documentId, XemeliosUser user, MySqlDataLayer msLayer) {
+ super();
+ this.documentId=documentId;
+ this.msLayer = msLayer;
+ this.user=user;
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ if("cg-etat".equals(documentId)) {
+ prepareCompteGestionEtat();
+ } else {
+ getNotifier().notifyThreadStop(this);
+ throw new RuntimeException("PdfPreparator does not know how to prepare "+documentId);
+ }
+ getNotifier().notifyThreadStop(this);
+ }
+
+ @Override
+ public String getInformations() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\t").append(getName()).append(":");
+ if(isAlive()) {
+ sb.append("PdfPreparator<"+documentId+"> running.");
+ } else {
+ if(isStarted()) {
+ sb.append("PdfPreparator<"+documentId+"> fully terminated.");
+ } else {
+ sb.append("PdfPreparator<"+documentId+"> idle");
+ }
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+ protected void prepareCompteGestionEtat() {
+ Connection con = null;
+ try {
+ con = PoolManager.getInstance().getConnection();
+ String createTable =
+ "CREATE TABLE IF NOT EXISTS PDF_CREATION ( "+
+ "DOCUMENT_ID VARCHAR(100) NOT NULL, "+
+ "ETAT_ID VARCHAR(100) NOT NULL, "+
+ "COLLECTIVITE VARCHAR(15) NOT NULL, "+
+ "BUDGET VARCHAR(15) NOT NULL, "+
+ "EXERCICE INTEGER, "+
+ "CREATION_STATUS INTEGER ) ENGINE MYISAM";
+ con.createStatement().executeUpdate(createTable);
+ DocumentModel dm = BatchRunner.getInstance().getDocuments().getDocumentById(documentId);
+ TPersistenceConfig pc = msLayer.getPersistenceConfig(dm, user);
+ TDocument docP = pc.getLayer(msLayer.getLayerName()).getDocument(documentId);
+ PreparedStatement psCheck = con.prepareStatement("SELECT 1 FROM PDF_CREATION WHERE DOCUMENT_ID='cg-etat' AND ETAT_ID=? AND COLLECTIVITE=? AND BUDGET=? AND EXERCICE=?");
+ PreparedStatement psInsert = con.prepareStatement("INSERT INTO PDF_CREATION (DOCUMENT_ID,ETAT_ID,COLLECTIVITE,BUDGET,EXERCICE) VALUES ('cg-etat',?,?,?,?)");
+ for(Iterator<TEtat> it=docP.getEtats().iterator();it.hasNext();) {
+ TEtat etat = it.next();
+ TTable table = etat.getMaintable();
+ String select = "SELECT DISTINCT COLLECTIVITE, BUDGET, EXERCICE FROM "+table.getBaseName();
+logger.debug(select);
+ ResultSet rs = con.createStatement().executeQuery(select);
+ while(rs.next()) {
+ String collectivite = rs.getString(1);
+ String budget = rs.getString(2);
+ int exercice = rs.getInt(3);
+ psCheck.setString(1,etat.getId());
+ psCheck.setString(2,collectivite);
+ psCheck.setString(3,budget);
+ psCheck.setInt(4, exercice);
+ ResultSet rs2 = psCheck.executeQuery();
+ if(!rs2.next()) {
+ psInsert.setString(1,etat.getId());
+ psInsert.setString(2,collectivite);
+ psInsert.setString(3,budget);
+ psInsert.setInt(4, exercice);
+ psInsert.executeUpdate();
+ }
+ rs2.close();
+ }
+ }
+ psCheck.close();
+ psInsert.close();
+ } catch(Exception ex) {
+ logger.error("prepareCompteGestionEtat",ex);
+ } finally {
+ if(con!=null) {
+ PoolManager.getInstance().releaseConnection(con);
+ con = null;
+ }
+ }
+ }
+ }
+}
--- /dev/null
+Manifest-version: 1.0
+Jar-Version: @version@
+Jar-Content: @name@
+Main-Class: fr.gouv.finances.dgfip.xemelios.batch.BatchRunner
\ No newline at end of file
--- /dev/null
+@SET CP=%CP%;%1
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>\r
+\r
+<!-- Authors: Chris Taylor, Ceki Gulcu. -->\r
+\r
+<!-- Version: 1.2 -->\r
+\r
+<!-- A configuration element consists of optional renderer\r
+elements,appender elements, categories and an optional root\r
+element. -->\r
+\r
+<!ELEMENT log4j:configuration (renderer*, appender*,(category|logger)*,root?,\r
+ categoryFactory?)>\r
+\r
+<!-- The "threshold" attribute takes a level value such that all -->\r
+<!-- logging statements with a level equal or below this value are -->\r
+<!-- disabled. -->\r
+\r
+<!-- Setting the "debug" or "configDebug" attributes enable the printing --> \r
+<!-- of internal log4j logging statements. -->\r
+\r
+<!-- By default, debug attribute is "null", meaning that we not touch --> \r
+<!-- internal log4j logging settings. --> \r
+\r
+ \r
+<!ATTLIST log4j:configuration\r
+ xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/" \r
+ threshold (all|debug|info|warn|error|fatal|off|null) "null"\r
+ debug (true|false|null) "null"\r
+>\r
+\r
+<!-- renderer elements allow the user to customize the conversion of -->\r
+<!-- message objects to String. -->\r
+\r
+<!ELEMENT renderer EMPTY>\r
+<!ATTLIST renderer\r
+ renderedClass CDATA #REQUIRED\r
+ renderingClass CDATA #REQUIRED\r
+>\r
+\r
+<!-- Appenders must have a name and a class. -->\r
+<!-- Appenders may contain an error handler, a layout, optional parameters -->\r
+<!-- and filters. They may also reference (or include) other appenders. -->\r
+<!ELEMENT appender (errorHandler?, param*, layout?, filter*, appender-ref*)>\r
+<!ATTLIST appender\r
+ name ID #REQUIRED\r
+ class CDATA #REQUIRED\r
+>\r
+\r
+<!ELEMENT layout (param*)>\r
+<!ATTLIST layout\r
+ class CDATA #REQUIRED\r
+>\r
+\r
+<!ELEMENT filter (param*)>\r
+<!ATTLIST filter\r
+ class CDATA #REQUIRED\r
+>\r
+\r
+<!-- ErrorHandlers can be of any class. They can admit any number of -->\r
+<!-- parameters. -->\r
+\r
+<!ELEMENT errorHandler (param*, root-ref?, logger-ref*, appender-ref?)> \r
+<!ATTLIST errorHandler\r
+ class CDATA #REQUIRED \r
+>\r
+\r
+<!ELEMENT root-ref EMPTY>\r
+\r
+<!ELEMENT logger-ref EMPTY>\r
+<!ATTLIST logger-ref\r
+ ref IDREF #REQUIRED\r
+>\r
+\r
+<!ELEMENT param EMPTY>\r
+<!ATTLIST param\r
+ name CDATA #REQUIRED\r
+ value CDATA #REQUIRED\r
+>\r
+\r
+\r
+<!-- The priority class is org.apache.log4j.Level by default -->\r
+<!ELEMENT priority (param*)>\r
+<!ATTLIST priority\r
+ class CDATA #IMPLIED\r
+ value CDATA #REQUIRED\r
+>\r
+\r
+<!-- The level class is org.apache.log4j.Level by default -->\r
+<!ELEMENT level (param*)>\r
+<!ATTLIST level\r
+ class CDATA #IMPLIED\r
+ value CDATA #REQUIRED\r
+>\r
+\r
+\r
+<!-- If no level element is specified, then the configurator MUST not -->\r
+<!-- touch the level of the named category. -->\r
+<!ELEMENT category (param*,(priority|level)?,appender-ref*)>\r
+<!ATTLIST category\r
+ class CDATA #IMPLIED\r
+ name CDATA #REQUIRED\r
+ additivity (true|false) "true" \r
+>\r
+\r
+<!-- If no level element is specified, then the configurator MUST not -->\r
+<!-- touch the level of the named logger. -->\r
+<!ELEMENT logger (level?,appender-ref*)>\r
+<!ATTLIST logger\r
+ name ID #REQUIRED\r
+ additivity (true|false) "true" \r
+>\r
+\r
+\r
+<!ELEMENT categoryFactory (param*)>\r
+<!ATTLIST categoryFactory \r
+ class CDATA #REQUIRED>\r
+\r
+<!ELEMENT appender-ref EMPTY>\r
+<!ATTLIST appender-ref\r
+ ref IDREF #REQUIRED\r
+>\r
+\r
+<!-- If no priority element is specified, then the configurator MUST not -->\r
+<!-- touch the priority of root. -->\r
+<!-- The root category always exists and cannot be subclassed. -->\r
+<!ELEMENT root (param*, (priority|level)?, appender-ref*)>\r
+\r
+\r
+<!-- ==================================================================== -->\r
+<!-- A logging event -->\r
+<!-- ==================================================================== -->\r
+<!ELEMENT log4j:eventSet (log4j:event*)>\r
+<!ATTLIST log4j:eventSet\r
+ xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/" \r
+ version (1.1|1.2) "1.2" \r
+ includesLocationInfo (true|false) "true"\r
+>\r
+\r
+\r
+\r
+<!ELEMENT log4j:event (log4j:message, log4j:NDC?, log4j:throwable?, \r
+ log4j:locationInfo?) >\r
+\r
+<!-- The timestamp format is application dependent. -->\r
+<!ATTLIST log4j:event\r
+ logger CDATA #REQUIRED\r
+ level CDATA #REQUIRED\r
+ thread CDATA #REQUIRED\r
+ timestamp CDATA #REQUIRED\r
+>\r
+\r
+<!ELEMENT log4j:message (#PCDATA)>\r
+<!ELEMENT log4j:NDC (#PCDATA)>\r
+\r
+<!ELEMENT log4j:throwable (#PCDATA)>\r
+\r
+<!ELEMENT log4j:locationInfo EMPTY>\r
+<!ATTLIST log4j:locationInfo\r
+ class CDATA #REQUIRED\r
+ method CDATA #REQUIRED\r
+ file CDATA #REQUIRED\r
+ line CDATA #REQUIRED\r
+>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration PUBLIC "-//Apache Software Foundation//DTD log4j Configuration 1.0//EN" "log4j.dtd">
+<log4j:configuration threshold="all" debug="false">
+ <appender name="rolling.file.appender" class="org.apache.log4j.RollingFileAppender">
+ <param name="File" value="${BATCH_LOG4J_FOLDER}/batch.log"/>
+ <param name="Append" value="true"/>
+ <param name="MaxFileSize" value="50MB"/>
+ <param name="MaxBackupIndex" value="10"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-5p [%c] %d{dd-MM-yyyy HH:mm:ss} : %m%n"/>
+ </layout>
+ </appender>
+ <root>
+ <level value="DEBUG"/>
+ <appender-ref ref="rolling.file.appender"/>
+ </root>
+</log4j:configuration>
\ No newline at end of file
--- /dev/null
+<html xmlns:o="urn:schemas-microsoft-com:office:office"\r
+xmlns:x="urn:schemas-microsoft-com:office:excel"\r
+xmlns="http://www.w3.org/TR/REC-html40">\r
+\r
+<head>\r
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">\r
+<meta name=ProgId content=Excel.Sheet>\r
+<style>\r
+<!--table\r
+ {mso-displayed-decimal-separator:"\.";\r
+ mso-displayed-thousand-separator:" ";}\r
+@page\r
+ {margin:.98in .79in .98in .79in;\r
+ mso-header-margin:.49in;\r
+ mso-footer-margin:.49in;}\r
+tr\r
+ {mso-height-source:auto;}\r
+col\r
+ {mso-width-source:auto;}\r
+br\r
+ {mso-data-placement:same-cell;}\r
+.style0\r
+ {mso-number-format:General;\r
+ text-align:general;\r
+ vertical-align:bottom;\r
+ white-space:nowrap;\r
+ mso-rotate:0;\r
+ mso-background-source:auto;\r
+ mso-pattern:auto;\r
+ color:windowtext;\r
+ font-size:10.0pt;\r
+ font-weight:400;\r
+ font-style:normal;\r
+ text-decoration:none;\r
+ font-family:Arial;\r
+ mso-generic-font-family:auto;\r
+ mso-font-charset:0;\r
+ border:none;\r
+ mso-protection:locked visible;\r
+ mso-style-name:Normal;\r
+ mso-style-id:0;}\r
+td\r
+ {mso-style-parent:style0;\r
+ padding-top:1px;\r
+ padding-right:1px;\r
+ padding-left:1px;\r
+ mso-ignore:padding;\r
+ color:windowtext;\r
+ font-size:10.0pt;\r
+ font-weight:400;\r
+ font-style:normal;\r
+ text-decoration:none;\r
+ font-family:Arial;\r
+ mso-generic-font-family:auto;\r
+ mso-font-charset:0;\r
+ mso-number-format:General;\r
+ text-align:general;\r
+ vertical-align:bottom;\r
+ border:none;\r
+ mso-background-source:auto;\r
+ mso-pattern:auto;\r
+ mso-protection:locked visible;\r
+ white-space:nowrap;\r
+ mso-rotate:0;}\r
+.axyusTitre\r
+ {\r
+ font-size:14.0pt;\r
+ font-weight:bold;\r
+ text-align:left;}\r
+.axyusNomsChamps\r
+ {\r
+ font-size:12.0pt;\r
+ font-weight:bold;\r
+ text-align:left;}\r
+.axyusText\r
+ {mso-style-parent:style0;\r
+ mso-number-format:"\@";\r
+ text-align:left;}\r
+.axyusInteger\r
+ {mso-style-parent:style0;\r
+ mso-number-format:0;\r
+ white-space:normal;}\r
+.axyusFloat\r
+ {mso-style-parent:style0;\r
+ mso-number-format:"0\.00";\r
+ white-space:normal;}\r
+.axyusDate\r
+ {mso-style-parent:style0;\r
+ mso-number-format:"Short Date";}\r
+-->\r
+</style>\r
+\r
+</head>\r
--- /dev/null
+driver.class=com.mysql.jdbc.Driver
+database.url=jdbc:mysql://localhost/xemelios?jdbcCompliantTruncation=false&dumpQueriesOnException=true
+user=xemelios
+password=Am/xL6*::
+validation.query=SELECT 1
+max.axtive=25
+max.wait=8
--- /dev/null
+.\xemelios-batches.bat -stop
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+./xemelios-batches.sh -stop
\ No newline at end of file
--- /dev/null
+@ECHO ON\r
+\r
+SET HERE=%~dp0%\..\r
+\r
+SetLocal\r
+\r
+SET JAVA_OPTIONS=-Xms64m -Xmx1024m -DBATCH_LOG4J_FOLDER=%HERE%\logs -Dlog4j.conf.file=%HERE%\conf\log4j.xml -Dpool.conf.file=%HERE%\conf\mysql.properties -Dxemelios.resources.location=%HERE%\resources\ -Dxemelios.date.format=dd/MM/yyyy\r
+\r
+SET CP=\r
+for %%F in (..\lib\*.jar) do @call CP.bat %%F\r
+REM for %%F in (..\lib\*.jar) do echo %%F\r
+\r
+start javaw %JAVA_OPTIONS% -cp %CP% fr.gouv.finances.dgfip.xemelios.batch.BatchRunner %HERE%\conf\batch-conf.xml %1\r
+\r
+EndLocal\r
--- /dev/null
+#!/bin/sh
+localDir=`dirname "$0"`/..
+if [ -n "${JAVA_HOME}" ] ; then
+ if [ -x "${JAVA_HOME}/bin/java" ] ; then
+ JAVACMD="${JAVA_HOME}/bin/java"
+ else
+ echo "** ERREUR: impossible d'executer java sous ${JAVA_HOME}"
+ exit 1
+ fi
+else
+ JAVACMD=`which java 2> /dev/null `
+ if [ -z "${JAVACMD}" ] ; then
+ JAVACMD=java
+ fi
+fi
+
+# Verification de la version de java (1.5.x) :
+javaVersion=`${JAVACMD} -version 2>&1 | grep "java version" | grep -e "1\.[56]"`
+if [ -z "${javaVersion}" ] ; then
+ echo "** ERREUR: La version de java n'est pas 1.5.x ou 1.6.x"
+ exit 1
+fi
+
+# Positionnement des options java :
+JAVA_OPTIONS="${JAVA_OPTIONS} -Xms64m -Xmx1024m"
+JAVA_OPTIONS="${JAVA_OPTIONS} -DBATCH_LOG4J_FOLDER=${localDir}/logs"
+JAVA_OPTIONS="${JAVA_OPTIONS} -Dlog4j.conf.file=${localDir}/conf/log4j.xml"
+JAVA_OPTIONS="${JAVA_OPTIONS} -Dpool.conf.file=${localDir}/conf/mysql.properties"
+JAVA_OPTIONS="${JAVA_OPTIONS} -Dxemelios.resources.location=${localDir}/resources/"
+JAVA_OPTIONS="${JAVA_OPTIONS} -Dxemelios.date.format=dd/MM/yyyy
+
+JAVA_CP=
+for f in `find ${localDir}/lib -name "*.jar"` ; do JAVA_CP=${JAVA_CP}:$f ; done
+
+# Pour le debogage a distance :
+#JAVA_OPTIONS="${JAVA_OPTIONS} -Xdebug"
+#JAVA_OPTIONS="${JAVA_OPTIONS} -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y"
+
+# Execution du batch :
+${JAVACMD} ${JAVA_OPTIONS} -cp ${JAVA_CP} fr.gouv.finances.dgfip.xemelios.batch.BatchRunner ${localDir}/conf/batch-conf.xml $@
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<project name="Xemelios-Imports" package="fr.gouv.finances.cp.xemelios.batch.imports.utils" output-dir="/home/chm/devel/XEMELIOS-NB/XEMELIOS/src/batch/java" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/xemelios" user="xemelios" password="xemelios" pk-prefix="" pk-ext="PK" full-prefix="" full-ext="Full" wrapper-prefix="" wrapper-ext="Wrapper" generator.class="com.labodev.tools.vogen.generator.XslGenerator">
+ <not-null-msg><![CDATA[should not be null]]></not-null-msg>
+ <too-long-msg-prfx><![CDATA[null]]></too-long-msg-prfx>
+ <too-long-msg-sufx><![CDATA[is tooo long]]></too-long-msg-sufx>
+ <types-mapping>
+ <type-mapping sql-type="varchar" java-type="java.lang.String"/>
+ <type-mapping sql-type="longtext" java-type="java.lang.String"/>
+ <type-mapping sql-type="int" java-type="java.lang.Integer"/>
+ <type-mapping sql-type="datetime" java-type="java.sql.Timestamp"/></types-mapping>
+ <param name="xsl.file.name" value="jar:/com/axyus/tools/vogen/generator/jdbcUtilsGenerator.xsl"/>
+ <table name="XEM_IMPORTS" pk-class-name="ImportVOPK" full-class-name="ImportVOFull" wrapper-class-name="ImportVOWrapper">
+ <column sql-name="UTI_LOGIN" java-name="utiLogin" sql-type="varchar" java-type="java.lang.String" sql-size="50" sql-precision="0" nullable="false" primary-key="false" generate-controls="true" column-id="UTI_LOGIN" auto-increment="false"/>
+ <column sql-name="IMPORT_ID" java-name="importId" sql-type="varchar" java-type="java.lang.String" sql-size="200" sql-precision="0" nullable="false" primary-key="true" generate-controls="true" column-id="IMPORT_ID" auto-increment="false"/>
+ <column sql-name="FILE_NAME" java-name="fileName" sql-type="varchar" java-type="java.lang.String" sql-size="200" sql-precision="0" nullable="false" primary-key="false" generate-controls="true" column-id="FILE_NAME" auto-increment="false"/>
+ <column sql-name="FILE_TYPE" java-name="fileType" sql-type="varchar" java-type="java.lang.String" sql-size="200" sql-precision="0" nullable="false" primary-key="false" generate-controls="true" column-id="FILE_TYPE" auto-increment="false"/>
+ <column sql-name="SUBMIT_DATE" java-name="submitDate" sql-type="datetime" java-type="java.sql.Timestamp" sql-size="0" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="SUBMIT_DATE" auto-increment="false"/>
+ <column sql-name="END_DATE" java-name="endDate" sql-type="datetime" java-type="java.sql.Timestamp" sql-size="0" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="END_DATE" auto-increment="false"/>
+ <column sql-name="STATUS" java-name="status" sql-type="int" java-type="java.lang.Integer" sql-size="10" sql-precision="0" nullable="false" primary-key="false" generate-controls="true" column-id="STATUS" auto-increment="false"/>
+ <column sql-name="COLLECTIVITE" java-name="collectivite" sql-type="varchar" java-type="java.lang.String" sql-size="15" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="COLLECTIVITE" auto-increment="false"/>
+ <column sql-name="BUDGET" java-name="budget" sql-type="varchar" java-type="java.lang.String" sql-size="24" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="BUDGET" auto-increment="false"/>
+ <column sql-name="COLLECTIVITE_LIB" java-name="collectiviteLib" sql-type="varchar" java-type="java.lang.String" sql-size="250" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="COLLECTIVITE_LIB" auto-increment="false"/>
+ <column sql-name="BUDGET_LIB" java-name="budgetLib" sql-type="varchar" java-type="java.lang.String" sql-size="250" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="BUDGET_LIB" auto-increment="false"/>
+ <column sql-name="ERROR_MESSAGE" java-name="errorMessage" sql-type="longtext" java-type="java.lang.String" sql-size="2147483647" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="ERROR_MESSAGE" auto-increment="false"/></table>
+ <table name="XEM_IMPORTS_FILES" pk-class-name="XemImportsFilesVOPK" full-class-name="XemImportsFilesVOFull" wrapper-class-name="XemImportsFilesVOWrapper">
+ <column sql-name="IMPORT_ID" java-name="importId" sql-type="varchar" java-type="java.lang.String" sql-size="200" sql-precision="0" nullable="false" primary-key="true" generate-controls="true" column-id="IMPORT_ID" auto-increment="false"/>
+ <column sql-name="SUB_FILE_NAME" java-name="subFileName" sql-type="longtext" java-type="java.lang.String" sql-size="2147483647" sql-precision="0" nullable="false" primary-key="true" generate-controls="true" column-id="SUB_FILE_NAME" auto-increment="false"/>
+ <column sql-name="FILE_TYPE" java-name="fileType" sql-type="varchar" java-type="java.lang.String" sql-size="200" sql-precision="0" nullable="false" primary-key="false" generate-controls="true" column-id="FILE_TYPE" auto-increment="false"/>
+ <column sql-name="STATUS" java-name="status" sql-type="int" java-type="java.lang.Integer" sql-size="10" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="STATUS" auto-increment="false"/>
+ <column sql-name="COLLECTIVITE" java-name="collectivite" sql-type="varchar" java-type="java.lang.String" sql-size="15" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="COLLECTIVITE" auto-increment="false"/>
+ <column sql-name="BUDGET" java-name="budget" sql-type="varchar" java-type="java.lang.String" sql-size="24" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="BUDGET" auto-increment="false"/>
+ <column sql-name="COLLECTIVITE_LIB" java-name="collectiviteLib" sql-type="varchar" java-type="java.lang.String" sql-size="250" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="COLLECTIVITE_LIB" auto-increment="false"/>
+ <column sql-name="BUDGET_LIB" java-name="budgetLib" sql-type="varchar" java-type="java.lang.String" sql-size="250" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="BUDGET_LIB" auto-increment="false"/>
+ <column sql-name="ERROR_MESSAGE" java-name="errorMessage" sql-type="longtext" java-type="java.lang.String" sql-size="2147483647" sql-precision="0" nullable="true" primary-key="false" generate-controls="true" column-id="ERROR_MESSAGE" auto-increment="false"/>
+ <for-list-class class-name="XemImportsFilesFL" function-name="getChildren">
+ <column column-ref="IMPORT_ID"/>
+ <column column-ref="SUB_FILE_NAME"/></for-list-class>
+ </table>
+</project>