Author: tchemit Date: 2013-12-20 17:07:29 +0100 (Fri, 20 Dec 2013) New Revision: 2954 Url: http://nuiton.org/projects/topia/repository/revisions/2954 Log: refs #2977: Extract csv api to a new topia-service-csv (move code from persistence module to service csv) Added: trunk/topia-service-csv/ trunk/topia-service-csv/LICENSE.txt trunk/topia-service-csv/README.txt trunk/topia-service-csv/changelog.txt trunk/topia-service-csv/pom.xml trunk/topia-service-csv/src/ trunk/topia-service-csv/src/main/ trunk/topia-service-csv/src/main/java/ trunk/topia-service-csv/src/main/java/org/ trunk/topia-service-csv/src/main/java/org/nuiton/ trunk/topia-service-csv/src/main/java/org/nuiton/topia/ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/CsvProgressModel.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/EntityCsvModel.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/TopiaCsvCommons.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/AbstractImportModel.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvFileImportResult.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvImportResult.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/EntityAssociationImportModel.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportModelFactory.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportStrategy.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/TopiaCsvImports.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/package-info.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/EntityAssociationExportModel.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportEntityVisitor.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportModelFactory.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/PrepareDataForExport.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/TopiaCsvExports.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/package-info.java trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/package-info.java trunk/topia-service-csv/src/main/resources/ trunk/topia-service-csv/src/test/ trunk/topia-service-csv/src/test/java/ trunk/topia-service-csv/src/test/java/org/ trunk/topia-service-csv/src/test/java/org/nuiton/ trunk/topia-service-csv/src/test/java/org/nuiton/topia/ trunk/topia-service-csv/src/test/resources/ Removed: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/ Modified: trunk/pom.xml trunk/topia-it/src/main/java/org/nuiton/topia/it/legacy/TopiaTestDaoSupplier.java trunk/topia-persistence/pom.xml trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaApplicationContext.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaConfigurationConstants.java trunk/topia-service-migration/pom.xml Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2013-12-20 16:05:54 UTC (rev 2953) +++ trunk/pom.xml 2013-12-20 16:07:29 UTC (rev 2954) @@ -207,6 +207,7 @@ <module>topia-it</module> <module>topia-service-replication</module> <module>topia-service-migration</module> + <module>topia-service-csv</module> </modules> <scm> Modified: trunk/topia-it/src/main/java/org/nuiton/topia/it/legacy/TopiaTestDaoSupplier.java =================================================================== --- trunk/topia-it/src/main/java/org/nuiton/topia/it/legacy/TopiaTestDaoSupplier.java 2013-12-20 16:05:54 UTC (rev 2953) +++ trunk/topia-it/src/main/java/org/nuiton/topia/it/legacy/TopiaTestDaoSupplier.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -1,5 +1,29 @@ package org.nuiton.topia.it.legacy; +/* + * #%L + * ToPIA :: IT + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + /** * Created on 12/20/13. * Property changes on: trunk/topia-it/src/main/java/org/nuiton/topia/it/legacy/TopiaTestDaoSupplier.java ___________________________________________________________________ Modified: svn:keywords - Author Date Id Revision + Author Date Id Revision HeadURL Modified: trunk/topia-persistence/pom.xml =================================================================== --- trunk/topia-persistence/pom.xml 2013-12-20 16:05:54 UTC (rev 2953) +++ trunk/topia-persistence/pom.xml 2013-12-20 16:07:29 UTC (rev 2954) @@ -48,16 +48,6 @@ </dependency> <dependency> - <groupId>org.nuiton</groupId> - <artifactId>nuiton-csv</artifactId> - </dependency> - - <dependency> - <groupId>org.nuiton</groupId> - <artifactId>nuiton-decorator</artifactId> - </dependency> - - <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> <scope>test</scope> @@ -84,11 +74,6 @@ </dependency> <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - </dependency> - - <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaApplicationContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaApplicationContext.java 2013-12-20 16:05:54 UTC (rev 2953) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaApplicationContext.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -1,5 +1,29 @@ package org.nuiton.topia.persistence; +/* + * #%L + * ToPIA :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + import com.google.common.collect.ImmutableMap; import org.nuiton.topia.persistence.support.TopiaListenableSupport; import org.nuiton.topia.persistence.support.TopiaServiceSupport; Property changes on: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaApplicationContext.java ___________________________________________________________________ Modified: svn:keywords - Author Date Id Revision + Author Date Id Revision HeadURL Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaConfigurationConstants.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaConfigurationConstants.java 2013-12-20 16:05:54 UTC (rev 2953) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaConfigurationConstants.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -1,5 +1,29 @@ package org.nuiton.topia.persistence; +/* + * #%L + * ToPIA :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + import org.hibernate.cfg.Environment; /** Property changes on: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaConfigurationConstants.java ___________________________________________________________________ Modified: svn:keywords - Author Date Id Revision + Author Date Id Revision HeadURL Property changes on: trunk/topia-service-csv ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/topia-service-csv/LICENSE.txt =================================================================== --- trunk/topia-service-csv/LICENSE.txt (rev 0) +++ trunk/topia-service-csv/LICENSE.txt 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Property changes on: trunk/topia-service-csv/LICENSE.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/topia-service-csv/README.txt =================================================================== --- trunk/topia-service-csv/README.txt (rev 0) +++ trunk/topia-service-csv/README.txt 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install Property changes on: trunk/topia-service-csv/README.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/topia-service-csv/changelog.txt =================================================================== --- trunk/topia-service-csv/changelog.txt (rev 0) +++ trunk/topia-service-csv/changelog.txt 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,63 @@ +2.2.1 chemit 20090903 + + * [FIX #38] manual migration service does not work on windows OS + * [FEATURE #40] clean manual migration service + * [FEATURE #42] add i18n in migration service + +-- chemit -- Thu, 03 Sep 2009 18:51:54 +0200 + +2.2.0 + * integrate in ToPIA project as org.nuiton.topia:topia-service-migration + * introduce a simpler migration service ManualMigrationEngine + - do only manual sql migration (using ToPIA persistence api) + - use only one callback handler of type ManualMigrationCallback + - use a ToPIA TMSVersion entity in package org.nuiton.migration + +1.1.0 + * migrate to nuiton + +1.0.3 chemit 20090511 + * bump versions (lutinproject, lutinutil, topia, maven-license-switcher-plugin) + * use doxia-modules-jrst instead of maven-jrst-plugin + * improve download section on site + +1.0.2 chemit 20090220 +* 20090220 [chemit] - use lutinproject 3.4 + +1.0.1 chemit 20081215 +* 20081215 [chemit] - new release for isis-fish :) follow release of topia + +1.0 chemit 20081210 + * 20081205 [chemit] - improve poms, use lutinproject 3.2, migrate tests to JUnit4 + +0.9.1 + * [chatellier] Correction d'un bug de recherche de mapping sous windows (\) + +0.9 + * <chemit> use lutinproject 3.0 + clean pom + use topia 2.0.27 + * <poussin> modif dans service de migration pour permettre a l'app de + faire la migration via le callback + +0.8 + + * 20071120 [chatellier] update topia-service site + * 20071115 [chatellier] apply hibernate code style to open/close session and + transaction + * 20071115 [chatellier] refractoring separate specifique topia service + and real migration code + * 20071115 [chatellier] add schema existance detection support + and dont migrate if there is no table + * 20071111 [chatellier] add support for callback handler + * 20071111 [chatellier] use cascade to calculate dependencies order + * 20071109 [chatellier] change schema creation process to + correct duplicate foreign key creation + * 20071109 [chatellier] add inherit support to calculate dependancies + +0.6 ??? ??? + + * 20070426 [chatellier] use lutinutil.Resources.getUrls() to get mappings + * 20070426 [chatellier] change finder migration to use Class.forName() + * 20070420 [chatellier] remove the 'V' letter in old mapping directories name + * 20070420 [chatellier] add support to look for hibernate mapping in a tree + structure of directories + * 20070418 [chatellier] add migration service \ No newline at end of file Property changes on: trunk/topia-service-csv/changelog.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/topia-service-csv/pom.xml =================================================================== --- trunk/topia-service-csv/pom.xml (rev 0) +++ trunk/topia-service-csv/pom.xml 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + ToPIA :: Service Migration + + $Id$ + $HeadURL$ + %% + Copyright (C) 2004 - 2010 CodeLutin + %% + This program 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 3 of the + License, or (at your option) any later version. + + This program 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 Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.nuiton</groupId> + <artifactId>topia</artifactId> + <version>3.0-SNAPSHOT</version> + </parent> + + <groupId>org.nuiton.topia</groupId> + <artifactId>topia-service-csv</artifactId> + <name>ToPIA :: Service Csv</name> + <description>To import or export with csv format</description> + + <properties> + <!-- Post Release configuration --> + <skipPostRelease>false</skipPostRelease> + </properties> + + <dependencies> + + <!-- Sibling dependencies --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>topia-persistence</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>topia-junit</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils</artifactId> + </dependency> + + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-decorator</artifactId> + </dependency> + + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-csv</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + </dependency> + + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + </dependency> + + <!-- Depencies for test--> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + </dependencies> + + <build> + <resources> + + <resource> + <directory>${maven.src.dir}/main/resources</directory> + <includes> + <include>**/*.hbm.xml</include> + <include>**/*.properties</include> + </includes> + </resource> + + </resources> + <plugins> + + </plugins> + </build> + +</project> Property changes on: trunk/topia-service-csv/pom.xml ___________________________________________________________________ Added: svn:mime-type + text/xml Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/CsvProgressModel.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/CsvProgressModel.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/CsvProgressModel.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/CsvProgressModel.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,46 @@ +package org.nuiton.topia.service.csv; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import java.io.Serializable; + +/** + * Csv progress model contract. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.14 + */ +public interface CsvProgressModel extends Serializable { + + long getNbSteps(); + + void setNbSteps(long nbSteps); + + float getProgress(); + + void setProgress(float progress); + + void incrementsProgress(); +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/EntityCsvModel.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/EntityCsvModel.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/EntityCsvModel.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/EntityCsvModel.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,255 @@ +package org.nuiton.topia.service.csv; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import org.nuiton.topia.persistence.TopiaEntities; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.metadata.TableMeta; +import org.nuiton.csv.ValueParserFormatter; +import org.nuiton.csv.ext.AbstractImportExportModel; +import org.nuiton.decorator.Decorator; + +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Map; + +/** + * A model to import / export entities into csv files. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.2 + */ +public class EntityCsvModel<T extends TopiaEntityEnum, E extends TopiaEntity> extends AbstractImportExportModel<E> { + + protected final TableMeta<T> tableMeta; + + protected boolean useOrdinalForEnum; + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> EntityCsvModel<T, E> newModel( + char separator, + TableMeta<T> tableMeta) { + return new EntityCsvModel<T, E>(separator, tableMeta); + } + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> EntityCsvModel<T, E> newModel( + char separator, + TableMeta<T> tableMeta, + String idHeader) { + return new EntityCsvModel<T, E>(separator, tableMeta, idHeader); + } + + @Override + public E newEmptyInstance() { + return (E) tableMeta.newEntity(); + } + + public void setUseOrdinalForEnum(boolean useOrdinalForEnum) { + this.useOrdinalForEnum = useOrdinalForEnum; + } + + public void addForeignKeyForExport(String propertyName, + Class<TopiaEntity> entityType) { + + Map<String, TopiaEntity> universe = Collections.emptyMap(); + + newColumnForExport(propertyName, + TopiaCsvCommons.newForeignKeyValue(entityType, + propertyName, + universe) + ); + } + + public <T> void addDecoratedForeignKeyForExport(String headerName, + String propertyName, + Decorator<T> decorator) { + modelBuilder.newColumnForExport( + headerName, + propertyName, + TopiaCsvCommons.newForeignKeyDecoratedValue(decorator)); + } + + public <E extends TopiaEntity> void addForeignKeyForImport(String headerName, + String propertyName, + Class<E> entityType, + Collection<E> entities, + Function<E, String> transform) { + + Map<String, E> universe = Maps.uniqueIndex(entities, transform); + + newMandatoryColumn(headerName, + propertyName, + TopiaCsvCommons.newForeignKeyValue(entityType, + propertyName, + universe) + ); + } + + public <E extends TopiaEntity> void addForeignKeyForAssociationForImport(String headerName, + String propertyName, + Class<E> entityType, + Collection<E> entities, + Function<E, String> transform) { + + Map<String, E> universe = Maps.uniqueIndex(entities, transform); + + newMandatoryColumn( + headerName, + propertyName, + TopiaCsvCommons.newForeignKeyValueAssociation(entityType, + propertyName, + universe) + ); + } + + public <E extends TopiaEntity> void addForeignKeyForImport(String propertyName, + Class<E> entityType, + Collection<E> entities) { + + Map<String, E> universe = Maps.uniqueIndex(entities, + TopiaEntities.getTopiaIdFunction()); + + newMandatoryColumn(propertyName, + TopiaCsvCommons.newForeignKeyValue(entityType, + propertyName, + universe) + ); + } + + public <E extends TopiaEntity> void addForeignKeyForImport(String propertyName, + Class<E> entityType, + Map<String, E> universe) { + + newMandatoryColumn(propertyName, + TopiaCsvCommons.newForeignKeyValue(entityType, + propertyName, + universe) + ); + } + public void addDefaultColumn(String propertyName, Class<?> type) { + addDefaultColumn(propertyName, propertyName, type); + } + + public void addDefaultColumn(String headerName, + String propertyName, + Class<?> type) { + + if (Date.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.DAY_TIME_SECOND_WITH_TIMESTAMP); + } else if (double.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.DOUBLE_PRIMITIVE); + } else if (Double.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.DOUBLE); + } else if (long.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.PRIMITIVE_LONG); + } else if (Long.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.LONG); + } else if (float.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.PRIMITIVE_FLOAT); + } else if (Float.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.FLOAT); + } else if (int.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.PRIMITIVE_INTEGER); + } else if (Integer.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.INTEGER); + } else if (boolean.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.PRIMITIVE_BOOLEAN); + } else if (Boolean.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName, + TopiaCsvCommons.BOOLEAN); + } else if (String.class.equals(type)) { + newColumnForImportExport( + headerName, + propertyName); + } else if (type.isEnum()) { + + Class<Enum> enumType = (Class<Enum>) type; + ValueParserFormatter<Enum> valueParserFormatter; + if (useOrdinalForEnum) { + valueParserFormatter = + TopiaCsvCommons.newEnumByOrdinalParserFormatter(enumType); + } else { + valueParserFormatter = + TopiaCsvCommons.newEnumByNameParserFormatter(enumType); + } + + newColumnForImportExport(headerName, + propertyName, + valueParserFormatter); + + } else { + + throw new IllegalStateException(String.format( + "For header %s, property %s, no specific handler " + + "found for type %s", headerName, propertyName, type)); + } + } + + protected EntityCsvModel(char separator, TableMeta<T> tableMeta) { + super(separator); + this.tableMeta = tableMeta; + } + + protected EntityCsvModel(char separator, TableMeta<T> tableMeta, + String idHeader) { + this(separator, tableMeta); + newColumnForImportExport(idHeader, TopiaEntity.PROPERTY_TOPIA_ID); + } +} \ No newline at end of file Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/TopiaCsvCommons.java (from rev 2949, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/TopiaCsvCommons.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/TopiaCsvCommons.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/TopiaCsvCommons.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,276 @@ +package org.nuiton.topia.service.csv; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.nuiton.topia.persistence.TopiaException; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.util.StringUtil; +import org.nuiton.csv.Common; +import org.nuiton.csv.ValueFormatter; +import org.nuiton.csv.ValueParser; +import org.nuiton.csv.ValueParserFormatter; +import org.nuiton.decorator.Decorator; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Map; + +/** + * More useful method added to {@link Common}. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public class TopiaCsvCommons extends Common { + + protected TopiaCsvCommons() { + // no instance of this helper + } + + public static final ValueParserFormatter<Date> DAY_TIME_SECOND_WITH_TIMESTAMP = + new DateValue("dd/MM/yyyy HH:mm:ss") { + + @Override + public Date parse(String value) throws ParseException { + + Date parse = super.parse(value); + if (parse != null) { + parse = new Timestamp(parse.getTime()); + } + return parse; + } + }; + + public static final ValueParserFormatter<Date> DAY_TIME_SECOND_MILI_WITH_TIMESTAMP = + new DateValue("dd/MM/yyyy HH:mm:ss.SSSS") { + + @Override + public Date parse(String value) throws ParseException { + + Date parse = super.parse(value); + if (parse != null) { + parse = new Timestamp(parse.getTime()); + } + return parse; + } + }; + public static final AssociationValueParser ASSOCIATION_VALUE_PARSER = new AssociationValueParser(); + + public static <E extends TopiaEntity> ForeignKeyValue<E> newForeignKeyValue(Class<E> type, String propertyName, Map<String, E> universe) { + return new ForeignKeyValue<E>(type, propertyName, universe); + } + + public static <E extends TopiaEntity> ForeignKeyValueForAssociation<E> newForeignKeyValueAssociation(Class<E> type, String propertyName, Map<String, E> universe) { + return new ForeignKeyValueForAssociation<E>(type, propertyName, universe); + } + + public static <E extends TopiaEntity> ValueFormatter<Collection<E>> newAssociationValueFormatter() { + return new AssociationValueParserFormatter<E>(null, null); + } + + public static <E> ForeignKeyDecoratedValue<E> newForeignKeyDecoratedValue(Decorator<E> decorator) { + return new ForeignKeyDecoratedValue<E>(decorator); + } + + /** + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ + public static class AssociationValueParser implements ValueParser<String[]> { + + @Override + public String[] parse(String value) throws ParseException { + String[] ids = value.split("\\|"); + return ids; + } + } + + /** + * @param <E> + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ + public static class AssociationValueParserFormatter<E extends TopiaEntity> implements ValueParserFormatter<Collection<E>> { + + protected final Class<E> entityType; + + protected final Map<String, E> universe; + + public AssociationValueParserFormatter( + Class<E> entityType, + Map<String, E> universe) { + this.entityType = entityType; + this.universe = universe; + } + + @Override + public Collection<E> parse(String value) throws ParseException { + Collection<E> result = Lists.newArrayList(); + if (StringUtils.isNotBlank(value)) { + + String[] ids = value.split("\\|"); + for (String id : ids) { + E association = universe.get(id); + association.setTopiaId(id); + result.add(association); + } + } + return result; + } + + @Override + public String format(Collection<E> e) { + + String value; + if (CollectionUtils.isEmpty(e)) { + value = ""; + } else { + Collection<String> ids = Lists.newArrayList(); + for (E e1 : e) { + ids.add(e1.getTopiaId()); + } + value = StringUtil.join(ids, "|", true); + } + return value; + } + } + + /** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ + public static class ForeignKeyDecoratedValue<E> implements ValueFormatter<E> { + + protected final Decorator<E> decorator; + + public ForeignKeyDecoratedValue(Decorator<E> decorator) { + this.decorator = decorator; + } + + @Override + public String format(E e) { + String value = ""; + if (e != null) { + value = decorator.toString(e); + } + return value; + } + } + + /** + * @param <E> + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ + public static class ForeignKeyValue<E extends TopiaEntity> implements ValueParserFormatter<E> { + + protected final String propertyName; + + protected final Class<E> entityType; + + protected final Map<String, E> universe; + + public ForeignKeyValue(Class<E> entityType, + String propertyName, + Map<String, E> universe) { + this.entityType = entityType; + this.propertyName = propertyName; + this.universe = universe; + } + + + @Override + public E parse(String value) throws ParseException { + E result = null; + if (StringUtils.isNotBlank(value)) { + + // get entity from universe + result = universe.get(value); + + if (result == null) { + + // can not find entity this is a big problem for us... + throw new TopiaException( + "Could not find entity of type " + + entityType.getSimpleName() + " with '" + + propertyName + "' = " + value); + } + } + return result; + } + + @Override + public String format(E e) { + String value = ""; + if (e != null) { + value = e.getTopiaId(); + } + return value; + } + } + + public static class ForeignKeyValueForAssociation<E extends TopiaEntity> implements ValueParser<Collection<E>> { + + protected final String propertyName; + + protected final Class<E> entityType; + + protected final Map<String, E> universe; + + public ForeignKeyValueForAssociation(Class<E> entityType, + String propertyName, + Map<String, E> universe) { + this.entityType = entityType; + this.propertyName = propertyName; + this.universe = universe; + } + + @Override + public Collection<E> parse(String value) throws ParseException { + E result = null; + if (StringUtils.isNotBlank(value)) { + + // get entity from universe + result = universe.get(value); + + if (result == null) { + + // can not find entity this is a big problem for us... + throw new TopiaException( + "Could not find entity with '" + propertyName + "' = " + value); + } + } + return Arrays.asList(result); + } + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/AbstractImportModel.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/AbstractImportModel.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/AbstractImportModel.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/AbstractImportModel.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,57 @@ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.service.csv.TopiaCsvCommons; + +import java.util.List; +import java.util.Map; + +/** + * Abstract import model which add the useful methdo about importing foreign keys. + * + * @param <E> type of entity to import + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public abstract class AbstractImportModel<E> extends org.nuiton.csv.ext.AbstractImportModel<E> { + + public AbstractImportModel(char separator) { + super(separator); + } + + @Override + public void pushCsvHeaderNames(List<String> headerNames) { + } + + public <E extends TopiaEntity> void newForeignKeyColumn(String headerName, String propertyName, Class<E> entityType, String foreignKeyName, Map<String, E> universe) { + newMandatoryColumn(headerName, propertyName, TopiaCsvCommons.newForeignKeyValue(entityType, foreignKeyName, universe)); + } + + public <E extends TopiaEntity> void newForeignKeyColumn(String propertyName, Class<E> entityType, String foreignKeyName, Map<String, E> universe) { + newMandatoryColumn(propertyName, propertyName, TopiaCsvCommons.newForeignKeyValue(entityType, foreignKeyName, universe)); + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvFileImportResult.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/CsvFileImportResult.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvFileImportResult.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvFileImportResult.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,112 @@ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.nuiton.topia.persistence.TopiaEntityEnum; + +import java.io.Serializable; +import java.util.Map; +import java.util.Set; + +/** + * To keep result of the import of a file. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public class CsvFileImportResult<T extends TopiaEntityEnum> implements Serializable { + + private static final long serialVersionUID = 1L; + + /** Name of the csv file to import. */ + protected final String importFileName; + + /** type of entity to import csv datas. */ + protected final Set<T> entityTypes; + + /** Count of created entities. */ + protected final Map<T, Integer> numberCreated; + + /** Count of updated entities. */ + protected final Map<T, Integer> numberUpdated; + + public static <T extends TopiaEntityEnum> CsvFileImportResult<T> newResult(String importFileName, T... universe) { + CsvFileImportResult<T> result = new CsvFileImportResult<T>( + importFileName, universe + ); + return result; + } + + public CsvFileImportResult(String importFileName, T... universe) { + this.importFileName = importFileName; + entityTypes = Sets.newHashSet(); + numberCreated = Maps.newHashMap(); + numberUpdated = Maps.newHashMap(); + for (T t : universe) { + numberCreated.put(t, 0); + numberUpdated.put(t, 0); + } + } + + public Set<T> getEntityTypes() { + return ImmutableSet.copyOf(entityTypes); + } + + public int getNumberCreated(T entityType) { + return getInteger(numberCreated, entityType); + } + + public int getNumberUpdated(T entityType) { + return getInteger(numberUpdated, entityType); + } + + public String getImportFileName() { + return importFileName; + } + + public void incrementsNumberCreated(T entityType) { + increments(numberCreated, entityType); + } + + public void incrementsNumberUpdated(T entityType) { + increments(numberUpdated, entityType); + } + + protected int getInteger(Map<T, Integer> map, T entityType) { + Integer result = map.get(entityType); + return result; + } + + protected void increments(Map<T, Integer> map, T entityType) { + Integer result = map.get(entityType); + if (result == 0) { + entityTypes.add(entityType); + } + map.put(entityType, ++result); + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvImportResult.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/CsvImportResult.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvImportResult.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/CsvImportResult.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,119 @@ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.service.csv.CsvProgressModel; + +import java.io.Serializable; + +/** + * A simple csv result bean just to keep the number of created or + * updated entities. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.2 + */ +public class CsvImportResult<T extends TopiaEntityEnum> implements Serializable { + + private static final long serialVersionUID = 1L; + + /** type of entity to import csv datas. */ + protected final T entityType; + + /** Name of the csv file to import. */ + protected final String importFileName; + + /** Flag to authorize to create entities not found in db. */ + protected final boolean createIfNotFound; + + /** Count of created entities. */ + protected int numberCreated; + + /** Count of updated entities. */ + protected int numberUpdated; + + protected final CsvProgressModel progressModel; + + public static <T extends TopiaEntityEnum> CsvImportResult<T> newResult(T entityType, + String importFileName, + boolean createIfNotFound) { + CsvImportResult<T> result = newResult(entityType, importFileName, + createIfNotFound, null); + return result; + } + + public static <T extends TopiaEntityEnum> CsvImportResult<T> newResult(T entityType, + String importFileName, + boolean createIfNotFound, + CsvProgressModel progressModel) { + CsvImportResult<T> result = new CsvImportResult<T>(entityType, importFileName, + createIfNotFound, progressModel); + return result; + } + + protected CsvImportResult(T entityType, + String importFileName, + boolean createIfNotFound, + CsvProgressModel progressModel) { + this.entityType = entityType; + this.importFileName = importFileName; + this.createIfNotFound = createIfNotFound; + this.progressModel = progressModel; + } + + public T getEntityType() { + return entityType; + } + + + public String getImportFileName() { + return importFileName; + } + + public int getNumberCreated() { + return numberCreated; + } + + public int getNumberUpdated() { + return numberUpdated; + } + + public boolean isCreateIfNotFound() { + return createIfNotFound; + } + + public void incrementsNumberCreated() { + numberCreated++; + } + + public void incrementsNumberUpdated() { + numberUpdated++; + } + + public CsvProgressModel getProgressModel() { + return progressModel; + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/EntityAssociationImportModel.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/EntityAssociationImportModel.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/EntityAssociationImportModel.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/EntityAssociationImportModel.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,76 @@ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.service.csv.TopiaCsvCommons; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.csv.ImportModel; + +import java.util.Map; + +/** + * A model to import associations of entities from csv files. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public class EntityAssociationImportModel<T extends TopiaEntityEnum> extends AbstractImportModel<Map<String, Object>> { + + protected final AssociationMeta meta; + + public static <T extends TopiaEntityEnum> ImportModel<Map<String, Object>> newImportModel(char separator, + AssociationMeta<T> meta) { + EntityAssociationImportModel<T> model = new EntityAssociationImportModel<T>( + separator, meta); + + // topiaId <-> topiaId + model.newMandatoryColumn( + TopiaEntity.PROPERTY_TOPIA_ID, + TopiaCsvCommons.<Map<String, Object>, String>newMapProperty(TopiaEntity.PROPERTY_TOPIA_ID) + ); + + // add association -> target + model.newMandatoryColumn( + meta.getName(), + TopiaCsvCommons.ASSOCIATION_VALUE_PARSER, + TopiaCsvCommons.<Map<String, Object>, String[]>newMapProperty("target") + ); + + return model; + } + + @Override + public Map<String, Object> newEmptyInstance() { + return null; + } + + public EntityAssociationImportModel(char separator, AssociationMeta<T> meta) { + super(separator); + this.meta = meta; + } + +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportModelFactory.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/ImportModelFactory.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportModelFactory.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportModelFactory.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,48 @@ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.topia.persistence.metadata.TableMeta; +import org.nuiton.csv.ImportModel; + +import java.util.Map; + +/** + * To produce import model. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public interface ImportModelFactory<T extends TopiaEntityEnum> { + + <E extends TopiaEntity> ImportModel<E> buildForImport(TableMeta<T> meta); + + ImportModel<Map<String, Object>> buildForImport(AssociationMeta<T> meta); + + boolean isNMAssociationMeta(AssociationMeta<T> meta); +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportStrategy.java (from rev 2949, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/ImportStrategy.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportStrategy.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/ImportStrategy.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,90 @@ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.topia.persistence.TopiaException; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.topia.persistence.metadata.TableMeta; +import org.nuiton.csv.Import; +import org.nuiton.csv.ImportToMap; + +import java.io.Reader; + +/** + * Strategy to import some stuff. + * <p/> + * Implements it and then you can use it with helper methods + * {@link TopiaCsvImports#importTable(Reader, ImportStrategy, TableMeta, CsvImportResult)}, + * {@link TopiaCsvImports#importAssociation(Reader, ImportStrategy, AssociationMeta, CsvImportResult)}. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public interface ImportStrategy<T extends TopiaEntityEnum> { + + /** @return the model factory (will be used to produce the model to import). */ + ImportModelFactory<T> getModelFactory(); + + /** + * Import a table given a {@code importer} with an optional csv result. + * + * @param meta type of table to import + * @param importer the csv importer + * @param csvResult optional object where to put csv import result + * @throws TopiaException if any db problem + */ + <E extends TopiaEntity> void importTable(TableMeta<T> meta, Import<E> importer, + CsvImportResult<T> csvResult) throws TopiaException; + + /** + * Import a table given a {@code importer} with an optional csv result, + * and return them. + * + * @param meta type of table to import + * @param importer the csv importer + * @param csvResult optional object where to put csv import result + * @return imported entities + * @throws TopiaException if any db problem + * @since 2.6.14 + */ + <E extends TopiaEntity> Iterable<E> importTableAndReturnThem(TableMeta<T> meta, Import<E> importer, + CsvImportResult<T> csvResult) throws TopiaException; + + /** + * Import a association given a {@code importer} with an optional csv result. + * + * @param meta type of association to import + * @param importer the csv importer + * @param csvResult optional object where to put csv import result + * @throws TopiaException if any db problem + */ + void importAssociation(AssociationMeta<T> meta, + ImportToMap importer, + CsvImportResult<T> csvResult) throws TopiaException; + + +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/TopiaCsvImports.java (from rev 2949, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/TopiaCsvImports.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/TopiaCsvImports.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/TopiaCsvImports.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,591 @@ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.csv.Import; +import org.nuiton.csv.ImportModel; +import org.nuiton.csv.ImportToMap; +import org.nuiton.topia.persistence.TopiaDao; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.TopiaException; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.topia.persistence.metadata.MetaFilenameAware; +import org.nuiton.topia.persistence.metadata.TableMeta; +import org.nuiton.topia.persistence.support.TopiaHibernateSupport; +import org.nuiton.topia.persistence.support.TopiaSqlSupport; +import org.nuiton.topia.persistence.util.TopiaEntityHelper; +import org.nuiton.topia.service.csv.CsvProgressModel; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * Helper for csv imports. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public class TopiaCsvImports { + + /** Logger. */ + private static final Log log = LogFactory.getLog(TopiaCsvImports.class); + + protected static final String UPDATE_ASSOCIATION = + "UPDATE %s SET %s = '%%s' WHERE topiaId ='%%s';"; + + protected static final String INSERT_ASSOCIATION = + "INSERT INTO %s (%s,%s) VALUES('%%s','%%s');"; + + protected TopiaCsvImports() { + // no instance of this helper + } + + /** + * Discover all files that can be imported (as a table or an association) from a zipfile. + * + * @param entryPrefix prefix where to find files in the zip + * @param possibleMetas list of possible meta to be imported + * @param zipFile zip file where to seek for csv files to import + * @param missingEntries to fill missing files + * @param <T> type of topia entity enum + * @param <M> type of data to import (table or association) + * @return the map of found files indexed by his meta + */ + public static <T extends TopiaEntityEnum, M extends MetaFilenameAware<T>> Map<M, ZipEntry> discoverEntries( + String entryPrefix, + Iterable<M> possibleMetas, + ZipFile zipFile, + List<String> missingEntries) { + + Map<M, ZipEntry> result = Maps.newLinkedHashMap(); + + // check that all mandatories + for (M entry : possibleMetas) { + String filename = entry.getFilename(); + ZipEntry zipEntry = zipFile.getEntry(entryPrefix + filename); + + if (zipEntry == null) { + missingEntries.add(filename); + } else { + result.put(entry, zipEntry); + } + } + return result; + } + + /** + * Discover all files that can be imported (as a table or an association) from a directory. + * + * @param possibleMetas list of possible meta to be imported + * @param directory directory where to seek for csv files to import + * @param missingEntries to fill missing files + * @param <T> type of topia entity enum + * @param <M> type of data to import (table or association) + * @return the map of found files indexed by his meta + */ + public static <T extends TopiaEntityEnum, M extends MetaFilenameAware<T>> Map<M, File> discoverEntries( + Iterable<M> possibleMetas, + File directory, + List<String> missingEntries) { + + Map<M, File> result = Maps.newLinkedHashMap(); + + // check that all mandatories + for (M entry : possibleMetas) { + String filename = entry.getFilename(); + File zipEntry = new File(directory, filename); + + if (zipEntry.exists()) { + result.put(entry, zipEntry); + } else { + missingEntries.add(filename); + } + } + return result; + } + + /** + * To import a table (given by his {@code meta}) from a reader and a strategy. + * <p/> + * Result of import can be stored in an optional csv result. + * + * @param reader where to read csv data + * @param importStrategy import strategy used to store csv data + * @param meta meta of the data + * @param csvResult optional csv result + * @param <T> type of entity enum + * @param <E> type of data + * @throws TopiaException if any db problem while storing datas + * @throws IOException if any pb while reading csv data + * @see ImportStrategy#importTable(TableMeta, Import, CsvImportResult) + */ + public static <T extends TopiaEntityEnum, E extends TopiaEntity> void importTable(Reader reader, + ImportStrategy<T> importStrategy, + TableMeta<T> meta, + CsvImportResult<T> csvResult) throws TopiaException, IOException { + + + if (log.isInfoEnabled()) { + log.info("Will import " + meta); + } + + ImportModel<E> model = importStrategy.getModelFactory().buildForImport(meta); + Import<E> importer = Import.newImport(model, reader); + try { + importStrategy.importTable(meta, importer, csvResult); + } finally { + importer.close(); + } + } + + /** + * To import a table (given by his {@code meta}) from a reader and a strategy. + * <p/> + * Result of import can be stored in an optional csv result. + * + * @param reader where to read csv data + * @param importStrategy import strategy used to store csv data + * @param meta meta of the data + * @param csvResult optional csv result + * @param <T> type of entity enum + * @param <E> type of data + * @throws TopiaException if any db problem while storing datas + * @throws IOException if any pb while reading csv data + * @see ImportStrategy#importTable(TableMeta, Import, CsvImportResult) + */ + public static <T extends TopiaEntityEnum, E extends TopiaEntity> Iterable<E> importTableAndReturn(Reader reader, + ImportStrategy<T> importStrategy, + TableMeta<T> meta, + CsvImportResult<T> csvResult) throws TopiaException, IOException { + + + if (log.isInfoEnabled()) { + log.info("Will import " + meta); + } + + ImportModel<E> model = importStrategy.getModelFactory().buildForImport(meta); + Import<E> importer = Import.newImport(model, reader); + try { + return importStrategy.importTableAndReturnThem(meta, importer, csvResult); + } finally { + importer.close(); + } + } + + /** + * To import a association (given by his {@code meta}) from a reader and a strategy. + * <p/> + * Result of import can be stored in an optional csv result. + * + * @param reader where to read csv data + * @param importStrategy import strategy used to store csv data + * @param meta meta of the data + * @param csvResult optional csv result + * @param <T> type of entity enum + * @throws TopiaException if any db problem while storing datas + * @throws IOException if any pb while reading csv data + * @see ImportStrategy#importAssociation(AssociationMeta, ImportToMap, CsvImportResult) + */ + public static <T extends TopiaEntityEnum> void importAssociation(Reader reader, + ImportStrategy<T> importStrategy, + AssociationMeta<T> meta, + CsvImportResult<T> csvResult) throws IOException, TopiaException { + + if (log.isInfoEnabled()) { + log.info("Will import " + meta); + } + + // load a association input + ImportModelFactory<T> modelFactory = importStrategy.getModelFactory(); + ImportModel<Map<String, Object>> model = + modelFactory.buildForImport(meta); + ImportToMap importer = ImportToMap.newImportToMap(model, reader, false); + + try { + importStrategy.importAssociation(meta, importer, csvResult); + + } finally { + importer.close(); + } + } + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> void importAllEntities(TopiaDao<E> dao, + TableMeta<T> meta, + Import<E> importer, + CsvImportResult<T> csvResult) throws TopiaException { + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + for (E entity : importer) { + + Map<String, Object> properties = meta.prepareCreate( + entity, entity.getTopiaId()); + E entityToSave = dao.create(properties); + + meta.copy(entity, entityToSave); + + if (csvResult != null) { + csvResult.incrementsNumberUpdated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + } + } + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> void importAllEntities(TopiaDao<E> dao, + TableMeta<T> meta, + Import<E> importer, + CsvImportResult<T> csvResult, + int nbRowBuffer) throws TopiaException { + + TopiaHibernateSupport hibernateSupport = null; // FIXME AThimel 23/11/13 Get an hibernate support instance + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + + int compt = 0; + for (E entity : importer) { + + Map<String, Object> properties = meta.prepareCreate( + entity, entity.getTopiaId()); + E entityToSave = dao.create(properties); + + meta.copy(entity, entityToSave); + + if (csvResult != null) { + csvResult.incrementsNumberUpdated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + compt++; + if (compt % nbRowBuffer == 0) { + // flush it + hibernateSupport.getHibernateSession().flush(); + } + } + } + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> Iterable<E> importAllEntitiesAndReturnThem(TopiaDao<E> dao, + TableMeta<T> meta, + Import<E> importer, + CsvImportResult<T> csvResult) throws TopiaException { + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + List<E> result = Lists.newArrayList(); + for (E entity : importer) { + + Map<String, Object> properties = meta.prepareCreate( + entity, entity.getTopiaId()); + E entityToSave = dao.create(properties); + + meta.copy(entity, entityToSave); + + if (csvResult != null) { + csvResult.incrementsNumberUpdated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + + result.add(entityToSave); + } + return result; + } + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> void importNotExistingEntities(TopiaDao<E> dao, + TableMeta<T> meta, + Map<String, TopiaEntity> universe, + Import<E> importer, + CsvImportResult<T> csvResult) throws TopiaException { + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + for (E entity : importer) { + + String topiaId = entity.getTopiaId(); + + Map<String, Object> properties = meta.prepareCreate(entity, null); + E existingEntity = dao.forProperties(properties).findAnyOrNull(); + if (existingEntity == null) { + + // new entity to create + E entityToSave = dao.create(properties); + String newTopiaId = entityToSave.getTopiaId(); + Date topiaCreateDate = entityToSave.getTopiaCreateDate(); + meta.copy(entity, entityToSave); + entityToSave.setTopiaId(newTopiaId); + entityToSave.setTopiaCreateDate(topiaCreateDate); + + if (log.isInfoEnabled()) { + log.info(String.format("Create entity [%s becomes %s] with naturalId %s", topiaId, newTopiaId, properties)); + } + universe.put(topiaId, entityToSave); + + if (csvResult != null) { + csvResult.incrementsNumberCreated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + } else { + // existing entity, nothing to create + // just add a ref into universe to make translation possible by foreign keys + + if (log.isDebugEnabled()) { + log.debug(String.format("Existing entity [%s] with naturalId %s, do not create anything", topiaId, properties)); + } + + universe.put(topiaId, existingEntity); + } + } + } + + public static <T extends TopiaEntityEnum> void importAssociation(TopiaSqlSupport sqlSupport, AssociationMeta<T> meta, + ImportToMap importer, + CsvImportResult<T> csvResult, + int nbRowBuffer) throws TopiaException { + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + T source = meta.getSource(); + T target = meta.getTarget(); + + StringBuilder builder = new StringBuilder(); + + String targetTableName = target.getContract().getSimpleName(); + String sourceTableName = source.getContract().getSimpleName(); + String table = targetTableName; + + String updateString = String.format(UPDATE_ASSOCIATION, table, sourceTableName); + + if (log.isDebugEnabled()) { + log.debug("Will apply " + updateString); + } + int compt = 0; + for (Map<String, Object> row : importer) { + String topiaId = (String) row.get(TopiaEntity.PROPERTY_TOPIA_ID); + String[] associations = (String[]) row.get("target"); + for (String association : associations) { + if (StringUtils.isNotEmpty(association)) { + builder.append(String.format(updateString, topiaId, association)).append('\n'); + compt++; + if (compt % nbRowBuffer == 0) { + // flush it + sqlSupport.executeSql(builder.toString()); + builder = new StringBuilder(); + } + } + } + if (csvResult != null) { + csvResult.incrementsNumberUpdated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + } + if (builder.length() > 0) { + sqlSupport.executeSql(builder.toString()); + } + } + + public static <T extends TopiaEntityEnum> void importNMAssociation(TopiaSqlSupport sqlSupport, + AssociationMeta<T> meta, + ImportToMap importer, + CsvImportResult<T> csvResult, + int nbRowBuffer) throws TopiaException { + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + T source = meta.getSource(); + T target = meta.getTarget(); + + StringBuilder builder = new StringBuilder(); + + + String targetTableName = target.getContract().getSimpleName(); + String sourceTableName = source.getContract().getSimpleName(); + + // relation *-* + String table = TopiaEntityHelper.getNormalizedAssociationTableName( + sourceTableName, targetTableName); + + String updateString = String.format(INSERT_ASSOCIATION, table, sourceTableName, targetTableName); + + if (log.isDebugEnabled()) { + log.debug("Will apply " + updateString); + } + int compt = 0; + for (Map<String, Object> row : importer) { + String topiaId = (String) row.get(TopiaEntity.PROPERTY_TOPIA_ID); + String[] associations = (String[]) row.get("target"); + for (String association : associations) { + if (StringUtils.isNotEmpty(association)) { + builder.append(String.format(updateString, topiaId, association)).append('\n'); + compt++; + if (compt % nbRowBuffer == 0) { + // flush it + sqlSupport.executeSql(builder.toString()); + builder = new StringBuilder(); + } + } + } + if (csvResult != null) { + csvResult.incrementsNumberUpdated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + } + if (builder.length() > 0) { + sqlSupport.executeSql(builder.toString()); + } + } + + public static <T extends TopiaEntityEnum> void importNMAssociation(TopiaSqlSupport sqlSupport, + AssociationMeta<T> meta, + Map<String, TopiaEntity> universe, + ImportToMap importer, + CsvImportResult<T> csvResult, + int nbRowBuffer) throws TopiaException { + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + T source = meta.getSource(); + T target = meta.getTarget(); + + StringBuilder builder = new StringBuilder(); + + + String targetTableName = target.getContract().getSimpleName(); + String sourceTableName = source.getContract().getSimpleName(); + + // relation *-* + String table = TopiaEntityHelper.getNormalizedAssociationTableName( + sourceTableName, targetTableName); + + String updateString = String.format(INSERT_ASSOCIATION, table, sourceTableName, targetTableName); + + if (log.isDebugEnabled()) { + log.debug("Will apply " + updateString); + } + int compt = 0; + for (Map<String, Object> row : importer) { + String topiaId = (String) row.get(TopiaEntity.PROPERTY_TOPIA_ID); + String[] associations = (String[]) row.get("target"); + for (String association : associations) { + if (StringUtils.isNotEmpty(association)) { + TopiaEntity targetEntity = universe.get(association); + Preconditions.checkNotNull(targetEntity, "Could not find target entity from id: " + association); + builder.append(String.format(updateString, topiaId, targetEntity.getTopiaId())).append('\n'); + compt++; + if (compt % nbRowBuffer == 0) { + // flush it + sqlSupport.executeSql(builder.toString()); + builder = new StringBuilder(); + } + } + } + if (csvResult != null) { + csvResult.incrementsNumberUpdated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + } + if (builder.length() > 0) { + sqlSupport.executeSql(builder.toString()); + } + } + + public static <T extends TopiaEntityEnum> void importAssociation(TopiaSqlSupport sqlSupport, + AssociationMeta<T> meta, + Map<String, TopiaEntity> universe, + ImportToMap importer, + CsvImportResult<T> csvResult, + int nbRowBuffer) throws TopiaException { + + CsvProgressModel progressModel = csvResult == null ? null : + csvResult.getProgressModel(); + + T source = meta.getSource(); + T target = meta.getTarget(); + + StringBuilder builder = new StringBuilder(); + + String targetTableName = target.getContract().getSimpleName(); + String sourceTableName = source.getContract().getSimpleName(); + String table = targetTableName; + + String updateString = String.format(UPDATE_ASSOCIATION, table, sourceTableName); + + if (log.isDebugEnabled()) { + log.debug("Will apply " + updateString); + } + int compt = 0; + for (Map<String, Object> row : importer) { + String topiaId = (String) row.get(TopiaEntity.PROPERTY_TOPIA_ID); + String[] associations = (String[]) row.get("target"); + for (String association : associations) { + if (StringUtils.isNotEmpty(association)) { + + TopiaEntity targetEntity = universe.get(association); + Preconditions.checkNotNull(targetEntity, "Could not find target entity from id: " + association); + builder.append(String.format(updateString, topiaId, targetEntity.getTopiaId())).append('\n'); + compt++; + if (compt % nbRowBuffer == 0) { + // flush it + sqlSupport.executeSql(builder.toString()); + builder = new StringBuilder(); + } + } + } + if (csvResult != null) { + csvResult.incrementsNumberUpdated(); + if (progressModel != null) { + progressModel.incrementsProgress(); + } + } + } + if (builder.length() > 0) { + sqlSupport.executeSql(builder.toString()); + } + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/package-info.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/package-info.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/package-info.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/in/package-info.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,31 @@ +/** + * Package for csv import of entities. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +package org.nuiton.topia.service.csv.in; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/EntityAssociationExportModel.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/out/EntityAssociationExportModel.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/EntityAssociationExportModel.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/EntityAssociationExportModel.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,65 @@ +package org.nuiton.topia.service.csv.out; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.csv.ExportModel; +import org.nuiton.csv.ext.AbstractExportModel; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.topia.service.csv.TopiaCsvCommons; + +/** + * A model to export associations of entities into csv files. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public class EntityAssociationExportModel<T extends TopiaEntityEnum, E extends TopiaEntity> extends AbstractExportModel<E> { + + protected final AssociationMeta meta; + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> ExportModel<E> newExportModel(char separator, + AssociationMeta<T> meta + ) { + EntityAssociationExportModel<T, E> model = new EntityAssociationExportModel<T, E>( + separator, + meta); + + // topiaId <-> topiaId + model.newColumnForExport(TopiaEntity.PROPERTY_TOPIA_ID); + + model.newColumnForExport( + meta.getName(), + TopiaCsvCommons.newAssociationValueFormatter() + ); + return model; + } + + EntityAssociationExportModel(char separator, AssociationMeta<T> meta) { + super(separator); + this.meta = meta; + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportEntityVisitor.java (from rev 2949, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/out/ExportEntityVisitor.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportEntityVisitor.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportEntityVisitor.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,212 @@ +package org.nuiton.topia.service.csv.out; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaException; +import org.nuiton.topia.persistence.EntityVisitor; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.TopiaPersistenceHelper; +import org.nuiton.util.TimeLog; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; + +/** + * Entity visitor to export data to csv files. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public class ExportEntityVisitor<T extends TopiaEntityEnum> implements EntityVisitor, Closeable { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ExportEntityVisitor.class); + + public static final TimeLog TIME_LOG = + new TimeLog(ExportEntityVisitor.class); + + /** Export for simple entity. */ + protected final Map<T, TopiaCsvExports.EntityExportContext<T>> entityExporters; + + protected final TopiaPersistenceHelper<T> persistenceHelper; + + public static <T extends TopiaEntityEnum> ExportEntityVisitor<T> newVisitor( + TopiaPersistenceHelper<T> persistenceHelper, + Map<T, TopiaCsvExports.EntityExportContext<T>> entityExporters) { + return new ExportEntityVisitor<T>( + persistenceHelper, + entityExporters + ); + } + + public ExportEntityVisitor(TopiaPersistenceHelper<T> persistenceHelper, + Map<T, TopiaCsvExports.EntityExportContext<T>> entityExporters) { + this.persistenceHelper = persistenceHelper; + this.entityExporters = entityExporters; + } + + public <E extends TopiaEntity> void export(Iterable<E> entities) { + for (E entity : entities) { + export(entity); + } + } + + public void export(TopiaEntity entity) { + Preconditions.checkNotNull(entity); + long s1 = TimeLog.getTime(); + try { + entity.accept(this); + } catch (TopiaException e) { + throw new TopiaException( + "Could not export entity " + entity.getTopiaId(), e); + } finally { + TIME_LOG.log(s1, "export::" + entity.getTopiaId()); + } + } + + @Override + public void start(TopiaEntity entity) { + String topiaId = entity.getTopiaId(); + try { + if (log.isDebugEnabled()) { + log.debug("Starts export of entity " + topiaId); + } + TopiaCsvExports.EntityExportContext entityExporter = + getEntityContext(entity.getClass()); + Preconditions.checkNotNull(entityExporter); + entityExporter.write(entity); + } catch (Exception e) { + throw new TopiaException( + "Could not export entity " + entity, e); + } finally { + if (log.isDebugEnabled()) { + log.debug("Ends export of entity " + topiaId); + } + } + } + + @Override + public void end(TopiaEntity entity) { + try { + if (log.isDebugEnabled()) { + log.debug("Starts export of association of entity " + + entity.getTopiaId()); + } + TopiaCsvExports.EntityExportContext entityExporter = + getEntityContext(entity.getClass()); + Preconditions.checkNotNull(entityExporter); + entityExporter.writeAssociations(entity); + } catch (Exception e) { + throw new TopiaException( + "Could not export associations of entity " + entity, e); + } finally { + if (log.isDebugEnabled()) { + log.debug("Ends export of association of entity " + + entity.getTopiaId()); + } + } + } + + + @Override + public void visit(TopiaEntity entity, String propertyName, + Class<?> type, Object value) { + } + + @Override + public void visit(TopiaEntity entity, + String propertyName, + Class<?> collectionType, + Class<?> type, + Object value) { + + if (TopiaEntity.class.isAssignableFrom(type) && + getEntityContext((Class<? extends TopiaEntity>) type) != null) { + Collection<?> cValue = (Collection<?>) value; + + if (CollectionUtils.isNotEmpty(cValue)) { + + visitEntityCollection(entity, + propertyName, + collectionType, + type, + cValue); + } + } + } + + protected void visitEntityCollection(TopiaEntity entity, + String propertyName, + Class<?> collectionType, + Class<?> type, + Collection<?> cValue) { + for (Object currentValue : cValue) { + try { + ((TopiaEntity) currentValue).accept(this); + } catch (TopiaException e) { + if (log.isErrorEnabled()) { + log.error("Can not visit entity " + currentValue, e); + } + } + } + } + + @Override + public void visit(TopiaEntity entity, + String propertyName, + Class<?> collectionType, Class<?> type, + int index, + Object value) { + + // nothing to do + } + + @Override + public void close() throws IOException { + + // use at the end of visit (or later) + + for (TopiaCsvExports.EntityExportContext<T> exportContext : entityExporters.values()) { + exportContext.close(); + } + } + + @Override + public void clear() { + // prefer use the close api + } + + protected TopiaCsvExports.EntityExportContext getEntityContext(Class<? extends TopiaEntity> entityType) { + T entityEnum = persistenceHelper.getEntityEnum(entityType); + return entityEnum == null ? null : entityExporters.get(entityEnum); + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportModelFactory.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/out/ExportModelFactory.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportModelFactory.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/ExportModelFactory.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,44 @@ +package org.nuiton.topia.service.csv.out; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.topia.persistence.metadata.TableMeta; +import org.nuiton.csv.ExportModel; + +/** +* To produce export model. +* +* @author tchemit <chemit@codelutin.com> +* @since 2.6.12 +*/ +public interface ExportModelFactory<T extends TopiaEntityEnum> { + + <E extends TopiaEntity> ExportModel<E> buildForExport(TableMeta<T> meta); + + <E extends TopiaEntity> ExportModel<E> buildForExport(AssociationMeta<T> associationMeta); +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/PrepareDataForExport.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/out/PrepareDataForExport.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/PrepareDataForExport.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/PrepareDataForExport.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,43 @@ +package org.nuiton.topia.service.csv.out; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.topia.persistence.metadata.TableMeta; + +/** + * Prepare data to export. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public interface PrepareDataForExport<T extends TopiaEntityEnum> { + + <E extends TopiaEntity> Iterable<E> prepareData(TableMeta<T> tableMeta); + + <E extends TopiaEntity> Iterable<E> prepareData(AssociationMeta<T> associationMeta); +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/TopiaCsvExports.java (from rev 2949, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/out/TopiaCsvExports.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/TopiaCsvExports.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/TopiaCsvExports.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,407 @@ +package org.nuiton.topia.service.csv.out; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaException; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaEntityEnum; +import org.nuiton.topia.persistence.metadata.AssociationMeta; +import org.nuiton.topia.persistence.metadata.MetaFilenameAware; +import org.nuiton.topia.persistence.metadata.Metadatas; +import org.nuiton.topia.persistence.metadata.TableMeta; +import org.nuiton.util.TimeLog; +import org.nuiton.csv.Export; +import org.nuiton.csv.ExportModel; +import org.nuiton.csv.ext.RepeatableExport; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.Writer; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * Helper for csv exports. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +public class TopiaCsvExports { + + /** Logger. */ + private static final Log log = LogFactory.getLog(TopiaCsvExports.class); + + + public static final TimeLog TIME_LOG = new TimeLog(TopiaCsvExports.class); + + + protected TopiaCsvExports() { + // no instance of this helper + } + + public static <T extends TopiaEntityEnum> String exportData(TableMeta<T> tableMeta, + ExportModelFactory<T> modelFactory, + PrepareDataForExport<T> prepareDataForExport) { + + + long s1 = TimeLog.getTime(); + Export<TopiaEntity> export = prepareExport(tableMeta, modelFactory, prepareDataForExport); + TIME_LOG.log(s1, "exportData::prepareExport"); + long s2 = TimeLog.getTime(); + String result; + try { + result = export.toString(Charsets.UTF_8); + } catch (Exception eee) { + throw new TopiaException("Can not export datas", eee); + } + TIME_LOG.log(s2, "exportData::exportToString"); + return result; + } + + public static <T extends TopiaEntityEnum> void exportData(TableMeta<T> tableMeta, + ExportModelFactory<T> modelFactory, + PrepareDataForExport<T> prepareDataForExport, + File file) { + + if (log.isInfoEnabled()) { + log.info("Export table " + tableMeta + " to " + file); + } + long s1 = TimeLog.getTime(); + Export<TopiaEntity> export = prepareExport(tableMeta, modelFactory, prepareDataForExport); + TIME_LOG.log(s1, "exportDatas::prepareExport"); + long s2 = TimeLog.getTime(); + try { + export.write(file, Charsets.UTF_8); + } catch (Exception eee) { + throw new TopiaException("Can not export datas", eee); + } + TIME_LOG.log(s2, "exportData::exportToFile"); + } + + public static <T extends TopiaEntityEnum> void exportData(AssociationMeta<T> associationMeta, + ExportModelFactory<T> modelFactory, + PrepareDataForExport<T> prepareDataForExport, + File file) { + + if (log.isInfoEnabled()) { + log.info("Export association " + associationMeta + " to " + file); + } + long s1 = TimeLog.getTime(); + + Export<TopiaEntity> export = prepareExport(associationMeta, modelFactory, prepareDataForExport); + TIME_LOG.log(s1, "exportData::prepareExport"); + + long s2 = TimeLog.getTime(); + try { + export.write(file, Charsets.UTF_8); + } catch (Exception eee) { + throw new TopiaException("Can not export datas", eee); + } + TIME_LOG.log(s2, "exportData::exportToFile"); + } + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> Export<E> prepareExport(TableMeta<T> tableMeta, + ExportModelFactory<T> modelFactory, + PrepareDataForExport<T> prepareDataForExport) { + + Iterable<E> datas = prepareDataForExport.prepareData(tableMeta); + ExportModel<E> model = modelFactory.buildForExport(tableMeta); + return Export.newExport(model, datas); + } + + public static <T extends TopiaEntityEnum, E extends TopiaEntity> Export<E> prepareExport(AssociationMeta<T> associationMeta, + ExportModelFactory<T> modelFactory, + PrepareDataForExport<T> prepareDataForExport) { + + Iterable<E> datas = prepareDataForExport.prepareData(associationMeta); + ExportModel<E> model = modelFactory.buildForExport(associationMeta); + return Export.newExport(model, datas); + } + + public static <T extends TopiaEntityEnum> Map<T, EntityExportContext<T>> createReplicateEntityVisitorContexts(ExportModelFactory<T> modelFactory, + MetaFilenameAware<T>[] entityMetas, + Multimap<T, MetaFilenameAware<T>> associations, + File container) { + + Preconditions.checkNotNull(modelFactory); + Preconditions.checkNotNull(entityMetas); + Preconditions.checkNotNull(associations); + Preconditions.checkNotNull(container); + + Map<T, EntityExportContext<T>> contexts = Maps.newHashMap(); + + for (MetaFilenameAware<T> entityMeta : entityMetas) { + TableMeta<T> meta = (TableMeta<T>) entityMeta; + + ExportModel<TopiaEntity> model = modelFactory.buildForExport(meta); + + EntityExportContext<T> exportContext = EntityExportContext.newExportContext( + model, + meta, + container); + + T source = meta.getSource(); + + contexts.put(source, exportContext); + + for (MetaFilenameAware<T> metaFilenameAware : associations.get(source)) { + AssociationMeta<T> associationMeta = + (AssociationMeta<T>) metaFilenameAware; + + ExportModel<TopiaEntity> associationModel = + modelFactory.buildForExport(associationMeta); + exportContext.addAssociationExportContext(associationMeta, + associationModel, + container); + } + } + return contexts; + } + + + public static <T extends TopiaEntityEnum> Map<T, EntityExportContext<T>> createReplicateEntityVisitorContexts(ExportModelFactory<T> modelFactory, + Iterable<TableMeta<T>> entityMetas, + Iterable<AssociationMeta<T>> associationMetas, + File container) { + + Preconditions.checkNotNull(modelFactory); + Preconditions.checkNotNull(entityMetas); + Preconditions.checkNotNull(associationMetas); + Preconditions.checkNotNull(container); + + Multimap<T, AssociationMeta<T>> associations = Metadatas.split(associationMetas); + Map<T, EntityExportContext<T>> contexts = Maps.newHashMap(); + + for (TableMeta<T> meta : entityMetas) { + + ExportModel<TopiaEntity> model = modelFactory.buildForExport(meta); + + EntityExportContext<T> exportContext = EntityExportContext.newExportContext( + model, + meta, + container); + + T source = meta.getSource(); + + contexts.put(source, exportContext); + + for (AssociationMeta<T> associationMeta : associations.get(source)) { + + ExportModel<TopiaEntity> associationModel = + modelFactory.buildForExport(associationMeta); + exportContext.addAssociationExportContext(associationMeta, + associationModel, + container); + } + } + return contexts; + } + + /** + * to export entity as csv files. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ + public static class EntityExportContext<T extends TopiaEntityEnum> implements Closeable { + + /** meta to export. */ + protected final TableMeta<T> meta; + + /** Exporter object. */ + protected final RepeatableExport export; + + /** Where to export datas. */ + protected final Writer writer; + + /** + * Unique list to store data to export. (will be shared with + * association export contexts.) + */ + private final List<TopiaEntity> data; + + /** Association export context for this type of entity. */ + protected final Collection<AssociationExportContext<T>> associationExportContexts; + + protected final File entryFile; + + public static <T extends TopiaEntityEnum> EntityExportContext<T> newExportContext( + ExportModel<TopiaEntity> model, + TableMeta<T> meta, + File container) { + return new EntityExportContext<T>(model, meta, container); + } + + protected EntityExportContext(ExportModel<TopiaEntity> model, + TableMeta<T> meta, + File container) { + Preconditions.checkNotNull(model); + Preconditions.checkNotNull(meta); + Preconditions.checkNotNull(container); + + this.meta = meta; + data = Lists.newArrayList(); + export = RepeatableExport.newExport(model, data, true); + entryFile = meta.newFile(container); + if (log.isDebugEnabled()) { + log.debug("Creates EntityExportContext::" + meta + " - " + + entryFile.getName()); + } + writer = meta.newWriter(container); + associationExportContexts = Lists.newArrayList(); + } + + public void addAssociationExportContext(AssociationMeta<T> meta, + ExportModel<TopiaEntity> model, + File container) { + associationExportContexts.add( + new AssociationExportContext<T>(model, + meta, + container, + data) + ); + } + + @Override + public void close() throws IOException { + + try { + if (export.isHeaderWritten()) { + + if (log.isInfoEnabled()) { + log.info("Export table " + meta + " to " + entryFile); + } + writer.flush(); + } else { + // this file was not used, delete it + FileUtils.deleteQuietly(entryFile); + } + } finally { + IOUtils.closeQuietly(writer); + for (AssociationExportContext<T> c : associationExportContexts) { + c.close(); + } + } + } + + public void write(TopiaEntity data) throws Exception { + this.data.add(data); + try { + export.write(writer); + } finally { + this.data.clear(); + } + } + + public void writeAssociations(TopiaEntity data) throws Exception { + this.data.add(data); + try { + for (AssociationExportContext<T> c : associationExportContexts) { + AssociationMeta<T> cMeta = c.meta; + boolean emptyChild = cMeta.isChildEmpty(data); + if (!emptyChild) { + c.write(); + } + } + } finally { + this.data.clear(); + } + } + } + + /** + * To export associations as csv files. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ + public static class AssociationExportContext<T extends TopiaEntityEnum> implements Closeable { + + /** association meta to export. */ + protected final AssociationMeta<T> meta; + + /** Exporter object. */ + protected final RepeatableExport export; + + /** Where to export datas. */ + protected final Writer writer; + + protected final File entryFile; + + protected AssociationExportContext(ExportModel<TopiaEntity> model, + AssociationMeta<T> meta, + File container, + List<TopiaEntity> data) { + Preconditions.checkNotNull(model); + Preconditions.checkNotNull(meta); + Preconditions.checkNotNull(container); + Preconditions.checkNotNull(data); + this.meta = meta; + + export = RepeatableExport.newExport(model, data, true); + + entryFile = meta.newFile(container); + if (log.isDebugEnabled()) { + log.debug("Creates AssociationExportContext::" + meta + + " - " + entryFile.getName()); + } + writer = meta.newWriter(container); + } + + @Override + public void close() throws IOException { + try { + if (export.isHeaderWritten()) { + + if (log.isInfoEnabled()) { + log.info("Export association " + meta + " to " + entryFile); + } + writer.flush(); + } else { + + // this file was not used, delete it + FileUtils.deleteQuietly(entryFile); + } + } finally { + IOUtils.closeQuietly(writer); + } + } + + public void write() throws Exception { + export.write(writer); + } + } +} Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/package-info.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/out/package-info.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/package-info.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/out/package-info.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,31 @@ +/** + * Package for csv export of entities. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +package org.nuiton.topia.service.csv.out; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ Copied: trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/package-info.java (from rev 2939, trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/package-info.java) =================================================================== --- trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/package-info.java (rev 0) +++ trunk/topia-service-csv/src/main/java/org/nuiton/topia/service/csv/package-info.java 2013-12-20 16:07:29 UTC (rev 2954) @@ -0,0 +1,31 @@ +/** + * Base package for csv import and export of entities. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.12 + */ +package org.nuiton.topia.service.csv; + +/* + * #%L + * ToPIA :: Service Csv + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ Modified: trunk/topia-service-migration/pom.xml =================================================================== --- trunk/topia-service-migration/pom.xml 2013-12-20 16:05:54 UTC (rev 2953) +++ trunk/topia-service-migration/pom.xml 2013-12-20 16:07:29 UTC (rev 2954) @@ -38,11 +38,6 @@ <name>ToPIA :: Service Migration</name> <description>Hibernate based migration service</description> - <properties> - <!-- Post Release configuration --> - <skipPostRelease>false</skipPostRelease> - </properties> - <dependencies> <!-- Sibling dependencies -->