View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.importexport.business;
35  
36  import fr.paris.lutece.portal.service.i18n.I18nService;
37  import fr.paris.lutece.portal.service.plugin.Plugin;
38  import fr.paris.lutece.portal.service.util.AppException;
39  import fr.paris.lutece.util.sql.DAOUtil;
40  
41  import java.util.ArrayList;
42  import java.util.Iterator;
43  import java.util.List;
44  import java.util.Locale;
45  import java.util.NoSuchElementException;
46  
47  import org.apache.commons.lang3.StringUtils;
48  
49  /**
50   * Abstract DAO to manage imports and exports
51   */
52  public abstract class AbstractImportExportDAO
53  {
54      protected static final String SQL_QUERY_GET_COLUMNS = " SELECT DISTINCT column_name, data_type FROM information_schema.columns WHERE table_name = ? ";
55      protected static final String SQL_QUERY_GET_COLUMNS_NAME = " SELECT DISTINCT column_name FROM information_schema.columns WHERE table_name = ? ";
56  
57      private static final String CONSTANT_SQL_INT = "int";
58      private static final String CONSTANT_SQL_LONG = "bigint";
59      private static final String CONSTANT_SQL_DOUBLE = "double";
60      private static final String CONSTANT_SQL_FLOAT = "float";
61      private static final String CONSTANT_SQL_REAL = "real";
62      private static final String CONSTANT_SQL_VARCHAR = "varchar";
63      private static final String CONSTANT_SQL_CHARACTER = "character";
64      private static final String CONSTANT_SQL_TEXT = "text";
65      private static final String CONSTANT_SQL_TIMESTAMP = "timestamp";
66      private static final String CONSTANT_SQL_DATE = "date";
67      private static final String CONSTANT_SQL_BYTE = "byte";
68      private static final String CONSTANT_SQL_BLOB = "blob";
69  
70      private static final String ERROR_MESSAGE_COLUMN_NOT_FOUND = "importexport.import_data.errors.columnNotFound";
71  
72      /**
73       * Get the list of columns of a table matching a given list of names. The result list is sorted in the same order as the list of columns name
74       * 
75       * @param listColumnNames
76       *            The list of names of columns to consider
77       * @param strTableName
78       *            The name of the database table
79       * @param plugin
80       *            The plugin to use the pool of
81       * @param locale
82       *            The locale to display errors in
83       * @return The list of columns, or an empty list if no columns was found.
84       * @throws AppException
85       *             If the table does not contain any column whithin a name of the columns name list
86       */
87      protected static List<TableColumn> getTableColumns( List<String> listColumnNames, String strTableName, Plugin plugin, Locale locale ) throws AppException
88      {
89          DAOUtil daoUtil = new DAOUtil( SQL_QUERY_GET_COLUMNS, plugin );
90          daoUtil.setString( 1, strTableName );
91          daoUtil.executeQuery( );
92          List<TableColumn> listColumns = new ArrayList<TableColumn>( listColumnNames.size( ) );
93          String strPrimaryKeyName = listColumnNames.get( 0 );
94          while ( daoUtil.next( ) )
95          {
96              String strColumnName = daoUtil.getString( 1 );
97              if ( strColumnName != null )
98              {
99                  strColumnName = strColumnName.toLowerCase( );
100             }
101             if ( listColumnNames.contains( strColumnName ) )
102             {
103                 String strColumnType = daoUtil.getString( 2 );
104                 TableColumnport/business/TableColumn.html#TableColumn">TableColumn tableColumn = new TableColumn( strColumnName, StringUtils.equals( strPrimaryKeyName, strColumnName ),
105                         getJavaTypeFromSqlString( strColumnType ) );
106                 listColumns.add( tableColumn );
107             }
108         }
109         daoUtil.free( );
110 
111         // We now sort elements of the list in the original order
112         List<TableColumn> listColumnsSorted = new ArrayList<TableColumn>( listColumns.size( ) );
113         for ( String strColumnName : listColumnNames )
114         {
115             Iterator<TableColumn> iterator = listColumns.iterator( );
116             TableColumn tableColumn;
117             try
118             {
119                 while ( ( tableColumn = iterator.next( ) ) != null )
120                 {
121                     if ( StringUtils.equals( strColumnName, tableColumn.getColumnName( ) ) )
122                     {
123                         listColumnsSorted.add( tableColumn );
124                         iterator.remove( );
125                         break;
126                     }
127                 }
128             }
129             catch( NoSuchElementException e )
130             {
131                 throw new AppException( I18nService.getLocalizedString( ERROR_MESSAGE_COLUMN_NOT_FOUND, locale ) );
132             }
133         }
134 
135         return listColumnsSorted;
136     }
137 
138     /**
139      * Get the list of columns names from the database
140      * 
141      * @param strTableName
142      *            The name of the table to get columns name from
143      * @param plugin
144      *            The plugin to use the pool of
145      * @return The list of names of columns of the database, or an empty list if no columns was found
146      */
147     public static List<String> getTableColumnsNames( String strTableName, Plugin plugin )
148     {
149         DAOUtil daoUtil = new DAOUtil( SQL_QUERY_GET_COLUMNS_NAME, plugin );
150         daoUtil.setString( 1, strTableName );
151         daoUtil.executeQuery( );
152         List<String> listColumnsName = new ArrayList<String>( );
153         while ( daoUtil.next( ) )
154         {
155             String strColumnName = daoUtil.getString( 1 );
156             listColumnsName.add( strColumnName );
157         }
158         daoUtil.free( );
159         return listColumnsName;
160     }
161 
162     /**
163      * Get the type of a column from its description
164      * 
165      * @param strColumnType
166      *            The description of the column type
167      * @return The column type, or null if no type was found
168      */
169     protected static ColumnType getJavaTypeFromSqlString( String strColumnType )
170     {
171         ColumnType columnType = null;
172         if ( strColumnType == null || StringUtils.isBlank( strColumnType ) )
173         {
174             return null;
175         }
176         String strColumnTypeSearch = strColumnType.toLowerCase( );
177         if ( StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_LONG ) )
178         {
179             columnType = ColumnType.TYPE_LONG;
180         }
181         else
182             if ( StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_INT ) )
183             {
184                 columnType = ColumnType.TYPE_INT;
185             }
186             else
187                 if ( StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_VARCHAR ) || StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_TEXT )
188                         || StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_CHARACTER ) )
189                 {
190                     columnType = ColumnType.TYPE_STRING;
191                 }
192                 else
193                     if ( StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_TIMESTAMP ) )
194                     {
195                         columnType = ColumnType.TYPE_TIMESTAMP;
196                     }
197                     else
198                         if ( StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_DATE ) )
199                         {
200                             columnType = ColumnType.TYPE_DATE;
201                         }
202                         else
203                             if ( StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_DOUBLE ) || StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_FLOAT )
204                                     || StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_REAL ) )
205                             {
206                                 columnType = ColumnType.TYPE_DOUBLE;
207                             }
208                             else
209                                 if ( StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_BYTE )
210                                         || StringUtils.contains( strColumnTypeSearch, CONSTANT_SQL_BLOB ) )
211                                 {
212                                     columnType = ColumnType.TYPE_BYTE;
213                                 }
214 
215         if ( columnType != null )
216         {
217             return columnType;
218         }
219 
220         return null;
221     }
222 }