r4359 - in trunk: . src/main/java/fr/ifremer/isisfish/logging src/main/java/fr/ifremer/isisfish/ui/input src/main/java/fr/ifremer/isisfish/ui/input/population
Author: echatellier Date: 2016-08-04 14:12:44 +0200 (Thu, 04 Aug 2016) New Revision: 4359 Url: http://forge.codelutin.com/projects/isis-fish/repository/revisions/4359 Log: fixes #8451: Log de toutes les modifications de la base Added: trunk/src/main/java/fr/ifremer/isisfish/logging/RegionChangeLogger.java Modified: trunk/pom.xml trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java trunk/src/main/java/fr/ifremer/isisfish/ui/input/population/PopulationEquationUI.jaxx Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2016-08-03 14:26:37 UTC (rev 4358) +++ trunk/pom.xml 2016-08-04 12:12:44 UTC (rev 4359) @@ -73,15 +73,7 @@ <scope>runtime</scope> </dependency> - <!-- temp for log4j 2 support (to remove with hibernate 5) --> <dependency> - <groupId>org.jboss.logging</groupId> - <artifactId>jboss-logging</artifactId> - <version>3.3.0.Final</version> - <scope>runtime</scope> - </dependency> - - <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>5.1</version> @@ -400,6 +392,12 @@ <artifactId>guava</artifactId> <version>19.0</version> </dependency> + + <dependency> + <groupId>com.opencsv</groupId> + <artifactId>opencsv</artifactId> + <version>3.8</version> + </dependency> <!-- Tests --> <dependency> @@ -556,8 +554,8 @@ <!-- Dependencies version --> <jaxxVersion>2.30.1</jaxxVersion> <eugeneVersion>2.14</eugeneVersion> - <topiaVersion>2.11</topiaVersion> - <hibernateVersion>4.3.11.Final</hibernateVersion> + <topiaVersion>2.12-SNAPSHOT</topiaVersion> + <hibernateVersion>5.1.0.Final</hibernateVersion> <nuitonI18nVersion>3.5</nuitonI18nVersion> <nuitonWidgetsVersion>1.1.1</nuitonWidgetsVersion> Added: trunk/src/main/java/fr/ifremer/isisfish/logging/RegionChangeLogger.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/logging/RegionChangeLogger.java (rev 0) +++ trunk/src/main/java/fr/ifremer/isisfish/logging/RegionChangeLogger.java 2016-08-04 12:12:44 UTC (rev 4359) @@ -0,0 +1,156 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2016 Ifremer, Code Lutin, Chatellier Eric + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 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 Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ +package fr.ifremer.isisfish.logging; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.Date; + +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.lang.time.DateFormatUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.hibernate.SessionFactory; +import org.hibernate.metadata.ClassMetadata; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.event.TopiaEntityEvent; +import org.nuiton.topia.event.TopiaEntityListener; +import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.persistence.TopiaEntity; + +import com.opencsv.CSVWriter; + +import fr.ifremer.isisfish.IsisFishRuntimeException; +import fr.ifremer.isisfish.datastore.RegionStorage; + +/** + * Listener topia qui ecrit un fichier de log avec toutes les modifications de la base de données + * dans un fichier changes.csv dans le répertoire de la région. + */ +public class RegionChangeLogger implements TopiaEntityListener { + + /** CSV separator char. */ + protected static final char CSV_SEPARATOR = ';'; + + /** CSV file name. */ + protected static final String CHANGES_FILE_NAME = "changes.csv"; + + /** Region storage. */ + protected RegionStorage regionStorage; + + /** Context. */ + protected TopiaContext context; + + public RegionChangeLogger(RegionStorage regionStorage, TopiaContext context) { + this.regionStorage = regionStorage; + this.context = context; + } + + @Override + public void create(TopiaEntityEvent event) { + addLogLine("CREATE", event.getEntity().getClass(), event.getEntity()); + } + + @Override + public void load(TopiaEntityEvent event) { + + } + + @Override + public void update(TopiaEntityEvent event) { + if (ArrayUtils.isNotEmpty(event.getDirtyProperties())) { + Class<? extends TopiaEntity> clazz = event.getEntity().getClass(); + SessionFactory sesionFactory = ((TopiaContextImpl)context).getHibernateFactory(); + ClassMetadata classMetadata = sesionFactory.getClassMetadata(clazz); + String[] propertyNames = classMetadata.getPropertyNames(); + + for (int dirtyProperty : event.getDirtyProperties()) { + String fieldName = propertyNames[dirtyProperty]; + + Object oldValue = event.getOldState()[dirtyProperty]; + String oldValueString = oldValue != null ? oldValue.toString() : ""; + Object newValue = event.getState()[dirtyProperty]; + String newValueString = newValue != null ? newValue.toString() : ""; + addLogLine("UPDATE", clazz, event.getEntity(), fieldName, oldValueString, newValueString); + } + } + } + + @Override + public void delete(TopiaEntityEvent event) { + addLogLine("DELETE", event.getEntity().getClass(), event.getEntity()); + } + + protected void addLogLine(String changeType, Class<? extends TopiaEntity> clazz, Object entity) { + addLogLine(changeType, clazz, entity, "", "", ""); + } + + protected void addLogLine(String changeType, Class<? extends TopiaEntity> clazz, Object entity, String field, String oldValue, String newValue) { + String date = DateFormatUtils.format(new Date(), "yyyy/MM/dd HH:mm:ss"); + String entityDisplayInfo = getEntityDisplayInfo(entity); + addLine(date, changeType, clazz.getSimpleName().replace("Impl", ""), entityDisplayInfo, field, oldValue, newValue); + } + + /** + * Add line into file. + * + * File is opened and closed each time (otherwize, content is not dumped to disk :( ) + * + * @param data data to add + */ + protected void addLine(String... data) { + File outFile = new File(regionStorage.getDirectory(), CHANGES_FILE_NAME); + boolean fileExists = outFile.length() > 0; + + try (CSVWriter out = new CSVWriter(new BufferedWriter(new FileWriter(outFile, true)), CSV_SEPARATOR)) { + // add header if necessary + if (!fileExists) { + out.writeNext(new String[] {"date","class","entity","field","oldvalue","newvalue"}); + } + + out.writeNext(data); + } catch (IOException ex) { + throw new IsisFishRuntimeException("Can't write log file", ex); + } + } + + /** + * Most of entity have a 'name' attribute. For those that don't, use toString(). + * + * @param entity entity + * @return display info + */ + protected String getEntityDisplayInfo(Object entity) { + String result; + try { + result = BeanUtils.getProperty(entity, "name"); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + result = entity.toString(); + } + return result; + } +} Property changes on: trunk/src/main/java/fr/ifremer/isisfish/logging/RegionChangeLogger.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Modified: trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java 2016-08-03 14:26:37 UTC (rev 4358) +++ trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java 2016-08-04 12:12:44 UTC (rev 4359) @@ -41,6 +41,7 @@ import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; +import fr.ifremer.isisfish.logging.RegionChangeLogger; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -123,19 +124,21 @@ TreeModel model = new DefaultTreeModel(null); inputUI.getFisheryRegionTree().setModel(model); } else { - FisheryRegion fisheryRegion = null; - RegionStorage regionStorage = null; - TopiaContext topiaContext = null; + FisheryRegion fisheryRegion; + RegionStorage regionStorage; + TopiaContext topiaContext; + RegionChangeLogger regionChangeLogger; // load region try { regionStorage = RegionStorage.getRegion(name); topiaContext = regionStorage.getStorage().beginTransaction(); + regionChangeLogger = new RegionChangeLogger(regionStorage, topiaContext); + // warning : this is a weak reference + topiaContext.addTopiaEntityListener(regionChangeLogger); fisheryRegion = RegionStorage.getFisheryRegion(topiaContext); - } catch (TopiaException ex) { + } catch (TopiaException | StorageException ex) { throw new IsisFishRuntimeException("Can't load region", ex); - } catch (StorageException ex) { - throw new IsisFishRuntimeException("Can't load region", ex); } // TODO echatellier 20110323 voir pour remplacer le binding @@ -158,6 +161,7 @@ inputUI.setContextValue(fisheryTreeHelper); inputUI.setContextValue(fisheryTreeModel); inputUI.setContextValue(topiaContext); + inputUI.setContextValue(regionChangeLogger); // just to keep reference (totally useless) inputUI.getCardlayoutPrincipal().show(inputUI.getInputPanePrincipal(),"normale"); Modified: trunk/src/main/java/fr/ifremer/isisfish/ui/input/population/PopulationEquationUI.jaxx =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/ui/input/population/PopulationEquationUI.jaxx 2016-08-03 14:26:37 UTC (rev 4358) +++ trunk/src/main/java/fr/ifremer/isisfish/ui/input/population/PopulationEquationUI.jaxx 2016-08-04 12:12:44 UTC (rev 4359) @@ -5,7 +5,7 @@ $Id$ $HeadURL$ %% - Copyright (C) 2009 - 2015 Ifremer, Code Lutin, Chatellier Eric + Copyright (C) 2009 - 2016 Ifremer, Code Lutin, Chatellier Eric %% This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as
participants (1)
-
echatellier@users.forge.codelutin.com