Author: echatellier Date: 2012-07-17 17:28:11 +0200 (Tue, 17 Jul 2012) New Revision: 1018 Url: http://forge.codelutin.com/repositories/revision/coser/1018 Log: fixes #1329 : Sauvegarder les rapports contr?\195?\180le et s?\195?\169lection en PDF Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java trunk/coser-business/src/main/java/fr/ifremer/coser/services/PublicationService.java trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2012-07-17 14:03:22 UTC (rev 1017) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2012-07-17 15:28:11 UTC (rev 1018) @@ -825,14 +825,50 @@ * Genère également les PDF des rapports de contrôle. * * @param project project to save - * @throws CoserBusinessException + * @throws CoserBusinessException + * @since 1.3 */ public void validControl(Project project) throws CoserBusinessException { - - project.getControl().setValidated(true); + Control control = project.getControl(); + control.setValidated(true); + + // sauvegarde + saveProjectControl(project); + + // generate control file as pdf + File projectsDirectory = config.getProjectsDirectory(); + File projectDirectory = new File(projectsDirectory, project.getName()); + File controlDirectory = new File(projectDirectory, CoserConstants.STORAGE_CONTROL_DIRECTORY); + File controlReportPdf = new File(controlDirectory, "control.pdf"); + publicationService.extractControlLogAsPDF(project, control, controlReportPdf); } + + /** + * Marque la selection comme validée et sauve le projet. + * + * Genère également les PDF des rapports de selection. + * + * @param project project to save + * @throws CoserBusinessException + * @since 1.3 + */ + public void validSelection(Project project, Selection selection) throws CoserBusinessException { + selection.setValidated(true); + + // sauvegarde + saveProjectSelection(project, selection); + + // generate control file as pdf + File projectsDirectory = config.getProjectsDirectory(); + File projectDirectory = new File(projectsDirectory, project.getName()); + File selectionsDirectory = new File(projectDirectory, CoserConstants.STORAGE_SELECTION_DIRECTORY); + File selectionDirectory = new File(selectionsDirectory, selection.getName()); + File selectionReportPdf = new File(selectionDirectory, "selection.pdf"); + publicationService.extractSelectionLogAsPDF(project, selection, selectionReportPdf); + } + /** * Creer une instance de selection "non sauvegardee" avec les données * de control (validée) du projet. Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/PublicationService.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/services/PublicationService.java 2012-07-17 14:03:22 UTC (rev 1017) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/PublicationService.java 2012-07-17 15:28:11 UTC (rev 1018) @@ -30,8 +30,13 @@ import java.awt.Color; import java.awt.Shape; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.PrintStream; +import java.io.StringWriter; +import java.io.Writer; import java.text.DateFormat; import java.text.NumberFormat; import java.util.ArrayList; @@ -67,11 +72,16 @@ import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.statistics.DefaultStatisticalCategoryDataset; import org.jfree.util.ShapeUtilities; +import org.w3c.dom.Document; +import org.xhtmlrenderer.pdf.ITextRenderer; +import com.lowagie.text.DocumentException; + import fr.ifremer.coser.CoserBusinessConfig; import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserConstants; import fr.ifremer.coser.CoserConstants.Category; +import fr.ifremer.coser.CoserUtils; import fr.ifremer.coser.bean.AbstractDataContainer; import fr.ifremer.coser.bean.Control; import fr.ifremer.coser.bean.Project; @@ -86,6 +96,7 @@ import fr.ifremer.coser.data.Length; import fr.ifremer.coser.storage.DataStorage; import fr.ifremer.coser.storage.MemoryDataStorage; +import freemarker.template.TemplateException; /** * Publication service (charts, reports, export, pdf...) @@ -421,11 +432,9 @@ out.println("</ul>"); out.println("</body></html>"); - } - catch (IOException ex) { + } catch (IOException ex) { throw new CoserBusinessException("Can't export errors", ex); - } - finally { + } finally { IOUtils.closeQuietly(out); } return exportHtmlFile; @@ -443,40 +452,93 @@ */ public File extractControlLogAsHTML(Project project, Control control) throws CoserBusinessException { File exportHtmlFile = null; - PrintStream out = null; + Writer out = null; try { exportHtmlFile = File.createTempFile("log-", ".html"); if (log.isInfoEnabled()) { log.info("Generating HTML report to " + exportHtmlFile.getAbsolutePath()); } - out = new PrintStream(exportHtmlFile, "utf-8"); + out = new OutputStreamWriter(new FileOutputStream(exportHtmlFile), "utf-8"); + extractControlLogAsHTML(project, control, out); + } catch (IOException ex) { + throw new CoserBusinessException("Can't export logs", ex); + } finally { + IOUtils.closeQuietly(out); + } + return exportHtmlFile; + } - out.println("<html><head>"); - out.println("<title>" + _("coser.business.publication.controllogexporttitle", project.getName())+ "</title>"); - out.println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"); - out.println("</head><body>"); + /** + * Extrait les logs des modifications faites sur un control au format html + * dans un flux donné. + * + * @param project project + * @param control data container + * @param out output stream + * @throws CoserBusinessException + * @throws IOException + */ + protected void extractControlLogAsHTML(Project project, Control control, Writer out) throws CoserBusinessException, IOException { + out.write("<html><head>"); + out.write("<title>" + _("coser.business.publication.controllogexporttitle", project.getName())+ "</title>"); + out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>"); + out.write("</head><body>"); - // header - out.println("<h1 style='text-align:center'>" + _("coser.business.publication.controllogexporttitle", project.getName()) + "</h1>"); + // header + out.write("<h1 style='text-align:center'>" + _("coser.business.publication.controllogexporttitle", project.getName()) + "</h1>"); - // partie detail - extractProjectReport(project, out); + // partie detail + extractProjectReport(project, out); - // partie specific : commandes - extractHistoryCommandReport(project, control, out); + // partie specific : commandes + extractHistoryCommandReport(project, control, out); - out.println("</body></html>"); + out.write("</body></html>"); + } + + /** + * Extrait les logs des modifications faites sur un control au format pdf. + * + * @param project project + * @param control data container + * @param pdfFile output pdf file + * @return extractedFile + * @throws CoserBusinessException + * @sincee 1.3 + * + * @see AbstractDataContainer#getHistoryCommands() + */ + public void extractControlLogAsPDF(Project project, Control control, File pdfFile) throws CoserBusinessException { + + OutputStream os = null; + try { + + Writer out = new StringWriter(); + extractControlLogAsHTML(project, control, out); + out.flush(); + + // get content as w3c document + Document document = CoserUtils.parseDocument(out.toString()); + + // render template output as pdf + os = new FileOutputStream(pdfFile); + + ITextRenderer renderer = new ITextRenderer(); + renderer.setDocument(document, null); + renderer.layout(); + renderer.createPDF(os); + + os.close(); + } catch (IOException ex) { + throw new CoserBusinessException("Can't generate log pdf", ex); + } catch (DocumentException ex) { + throw new CoserBusinessException("Can't generate log pdf", ex); + } finally { + IOUtils.closeQuietly(os); } - catch (IOException ex) { - throw new CoserBusinessException("Can't export logs", ex); - } - finally { - IOUtils.closeQuietly(out); - } - return exportHtmlFile; } - + /** * Extrait les logs des modifications faites sur une selection au format html. * @@ -489,46 +551,61 @@ */ public File extractSelectionLogAsHTML(Project project, Selection selection) throws CoserBusinessException { File exportHtmlFile = null; - PrintStream out = null; + Writer out = null; try { exportHtmlFile = File.createTempFile("log-", ".html"); if (log.isInfoEnabled()) { log.info("Generating HTML report to " + exportHtmlFile.getAbsolutePath()); } - out = new PrintStream(exportHtmlFile, "utf-8"); + out = new OutputStreamWriter(new FileOutputStream(exportHtmlFile), "utf-8"); + extractSelectionLogAsHTML(project, selection, out); + + } catch (IOException ex) { + throw new CoserBusinessException("Can't export logs", ex); + } finally { + IOUtils.closeQuietly(out); + } + return exportHtmlFile; + } - out.println("<html><head>"); - out.println("<title>" + _("coser.business.publication.selectionlogexporttitle", selection.getName(), project.getName())+ "</title>"); - out.println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"); - out.println("</head><body>"); + /** + * Extrait les logs des modifications faites sur une selection au format html + * dans le flux donné. + * + * @param project project + * @param selection data container + * @param out output stream + * @return extractedFile + * @throws IOException + * @throws CoserBusinessException + * + * @see AbstractDataContainer#getHistoryCommands() + */ + protected void extractSelectionLogAsHTML(Project project, Selection selection, Writer out) throws IOException, CoserBusinessException { + out.write("<html><head>"); + out.write("<title>" + _("coser.business.publication.selectionlogexporttitle", selection.getName(), project.getName())+ "</title>"); + out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>"); + out.write("</head><body>"); - // header - out.println("<h1 style='text-align:center'>" + _("coser.business.publication.selectionlogexporttitle", selection.getName(), project.getName()) + "</h1>"); + // header + out.write("<h1 style='text-align:center'>" + _("coser.business.publication.selectionlogexporttitle", selection.getName(), project.getName()) + "</h1>"); - // partie detail - extractProjectReport(project, out); + // partie detail + extractProjectReport(project, out); - // partie resumé de selection - out.println("<h2>" + _("coser.business.publication.selectionchoices") + "</h2>"); - out.println("<ul>"); - out.println("<li>" + _("coser.business.common.years") + " : " + StringUtils.join(selection.getSelectedYears(), ", ") + "</li>"); - out.println("<li>" + _("coser.business.common.strata") + " : " + StringUtils.join(selection.getSelectedStrata(), ", ") + "</li>"); - out.println("<li>" + _("coser.business.common.species") + " : " + StringUtils.join(selection.getSelectedSpecies(), ", ") + "</li>"); - out.println("</ul>"); + // partie resumé de selection + out.write("<h2>" + _("coser.business.publication.selectionchoices") + "</h2>"); + out.write("<ul>"); + out.write("<li>" + _("coser.business.common.years") + " : " + StringUtils.join(selection.getSelectedYears(), ", ") + "</li>"); + out.write("<li>" + _("coser.business.common.strata") + " : " + StringUtils.join(selection.getSelectedStrata(), ", ") + "</li>"); + out.write("<li>" + _("coser.business.common.species") + " : " + StringUtils.join(selection.getSelectedSpecies(), ", ") + "</li>"); + out.write("</ul>"); - // partie specific : commandes - extractHistoryCommandReport(project, selection, out); + // partie specific : commandes + extractHistoryCommandReport(project, selection, out); - out.println("</body></html>"); - } - catch (IOException ex) { - throw new CoserBusinessException("Can't export logs", ex); - } - finally { - IOUtils.closeQuietly(out); - } - return exportHtmlFile; + out.write("</body></html>"); } /** @@ -536,32 +613,74 @@ * * @param project project * @param out stream + * @throws IOException */ - protected void extractProjectReport(Project project, PrintStream out) { + protected void extractProjectReport(Project project, Writer out) throws IOException { DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, config.getLocale()); // date du rapport - out.println("<div style='text-align:right;font-style:italic'>" + + out.write("<div style='text-align:right;font-style:italic'>" + _("coser.business.publication.date") +" : " + dateFormat.format(new Date()) + "</div>"); // partie projet - out.println("<h2>" + _("coser.business.publication.projectdetails") + "</h2>"); - out.println("<ul>"); - out.println("<li>" + _("coser.business.publication.creationdate") + " : " + dateFormat.format(project.getCreationDate())); - out.println("<li>" + _("coser.business.publication.author") + " : " + project.getAuthor() + "</li>"); - out.println("<li>" + _("coser.business.publication.catchfilename") + " : " + commonService.getDataStorageFileName(project, Category.CATCH, null) + "</li>"); - out.println("<li>" + _("coser.business.publication.lengthfilename") + " : " + commonService.getDataStorageFileName(project, Category.LENGTH, null) + "</li>"); - out.println("<li>" + _("coser.business.publication.haulfilename") + " : " + commonService.getDataStorageFileName(project, Category.HAUL, null) + "</li>"); - out.println("<li>" + _("coser.business.publication.stratafilename") + " : " + commonService.getDataStorageFileName(project, Category.STRATA, null) + "</li>"); + out.write("<h2>" + _("coser.business.publication.projectdetails") + "</h2>"); + out.write("<ul>"); + out.write("<li>" + _("coser.business.publication.creationdate") + " : " + dateFormat.format(project.getCreationDate()) + "</li>"); + out.write("<li>" + _("coser.business.publication.author") + " : " + project.getAuthor() + "</li>"); + out.write("<li>" + _("coser.business.publication.catchfilename") + " : " + commonService.getDataStorageFileName(project, Category.CATCH, null) + "</li>"); + out.write("<li>" + _("coser.business.publication.lengthfilename") + " : " + commonService.getDataStorageFileName(project, Category.LENGTH, null) + "</li>"); + out.write("<li>" + _("coser.business.publication.haulfilename") + " : " + commonService.getDataStorageFileName(project, Category.HAUL, null) + "</li>"); + out.write("<li>" + _("coser.business.publication.stratafilename") + " : " + commonService.getDataStorageFileName(project, Category.STRATA, null) + "</li>"); if (StringUtils.isNotEmpty(project.getComment())) { - out.println("<li>" + _("coser.business.publication.comment") + " : " + project.getComment() + "</li>"); + out.write("<li>" + _("coser.business.publication.comment") + " : " + project.getComment() + "</li>"); } - out.println("</ul>"); + out.write("</ul>"); } /** + * Extrait les logs des modifications faites sur une selection au format pdf. + * + * @param project project + * @param selection data container + * @return extractedFile + * @throws CoserBusinessException + * @since 1.3 + * + * @see AbstractDataContainer#getHistoryCommands() + */ + public void extractSelectionLogAsPDF(Project project, Selection selection, File pdfFile) throws CoserBusinessException { + + OutputStream os = null; + try { + + Writer out = new StringWriter(); + extractSelectionLogAsHTML(project, selection, out); + out.flush(); + + // get content as w3c document + Document document = CoserUtils.parseDocument(out.toString()); + + // render template output as pdf + os = new FileOutputStream(pdfFile); + + ITextRenderer renderer = new ITextRenderer(); + renderer.setDocument(document, null); + renderer.layout(); + renderer.createPDF(os); + + os.close(); + } catch (IOException ex) { + throw new CoserBusinessException("Can't generate log pdf", ex); + } catch (DocumentException ex) { + throw new CoserBusinessException("Can't generate log pdf", ex); + } finally { + IOUtils.closeQuietly(os); + } + } + + /** * Partie commune aux export qui effectue en 2 passe la recuperation * des lignes d'erreur, la recuperation des données correspondant à * ces lignes dans les fichiers originaux et la sortie des erreurs. @@ -570,8 +689,9 @@ * @param container data container * @param out output stream * @throws CoserBusinessException + * @throws IOException */ - protected void extractHistoryCommandReport(Project project, AbstractDataContainer container, PrintStream out) throws CoserBusinessException { + protected void extractHistoryCommandReport(Project project, AbstractDataContainer container, Writer out) throws CoserBusinessException, IOException { // first get lines index to get content Set<String> catchLines = new HashSet<String>(); @@ -611,8 +731,8 @@ Map<String, String[]> strataContent = commonService.getOriginalContent(project, Category.STRATA, strataLines); // third, generate html report - out.println("<h2>" + _("coser.business.publication.datamodification") + "</h2>"); - out.println("<ol>"); + out.write("<h2>" + _("coser.business.publication.datamodification") + "</h2>"); + out.write("<ol>"); for (Command command : container.getHistoryCommands()) { Category category = null; String line = null; @@ -636,14 +756,14 @@ data = strataContent.get(line); break; } - out.println("<li>" + command.getLogString(container) + "<br/>"); - out.println("<tt style='color:#5F5A59'>" + StringUtils.join(data, ", ") + "</tt><br /></li>"); + out.write("<li>" + command.getLogString(container) + "<br/>"); + out.write("<tt style='color:#5F5A59'>" + StringUtils.join(data, ", ") + "</tt><br /></li>"); } else { - out.println("<li>" + command.getLogString(container) + "</li>"); + out.write("<li>" + command.getLogString(container) + "</li>"); } } - out.println("</ol>"); + out.write("</ol>"); } /** Modified: trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties =================================================================== --- trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties 2012-07-17 14:03:22 UTC (rev 1017) +++ trunk/coser-business/src/main/resources/i18n/coser-business_fr_FR.properties 2012-07-17 15:28:11 UTC (rev 1018) @@ -111,7 +111,7 @@ coser.business.publication.catchfilename=Nom du fichier captures coser.business.publication.comment=Commentaire coser.business.publication.controllogexporttitle=Rapport des modifications (projet %s) -coser.business.publication.creationdate=Date de créaction +coser.business.publication.creationdate=Date de création coser.business.publication.datamodification=Modifications sur les données coser.business.publication.date=Le coser.business.publication.errorexportlines=Lignes Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2012-07-17 14:03:22 UTC (rev 1017) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2012-07-17 15:28:11 UTC (rev 1018) @@ -154,11 +154,47 @@ } /** + * Test que la validation du controle fonctionne et produit bien le pdf + * de rapport. + * + * @throws CoserBusinessException + */ + @Test + public void testValidControl() throws CoserBusinessException { + Project project = createTestProject(projectService, false); + projectService.validControl(project); + + Assert.assertTrue(project.getControl().isValidated()); + Assert.assertTrue(new File(config.getProjectsDirectory(), + project.getName() + File.separator + "control" + File.separator + "control.pdf").exists()); + } + + /** * Test que les selections sont bien creer. * * @throws CoserBusinessException */ @Test + public void testValidSelection() throws CoserBusinessException { + Project project = createTestProject(projectService, true); + Selection selection = projectService.initProjectSelection(project); + selection.setName("titi"); + + projectService.createProjectSelection(project, selection); + projectService.validSelection(project, selection); + + Assert.assertTrue(selection.isValidated()); + Assert.assertTrue(new File(config.getProjectsDirectory(), + project.getName() + File.separator + "selections" + File.separator + + "titi" + File.separator + "selection.pdf").exists()); + } + + /** + * Test que les selections sont bien creer. + * + * @throws CoserBusinessException + */ + @Test public void testCreateSelection() throws CoserBusinessException { Project project = createTestProject(projectService, true); Selection selection = projectService.initProjectSelection(project); @@ -259,8 +295,6 @@ // doit recharger les données pour être correct strata = projectService.filterDataYearsAndGetStrata(project, selection, years3); Assert.assertEquals(3, strata.size()); - - } /** @@ -317,7 +351,6 @@ projectService.filterDataStrata(project, selection, Collections.singletonList("STR6")); species = projectService.getProjectSpecies(project, selection, allPpeciesType); Assert.assertEquals(4, species.size()); - } /** Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java 2012-07-17 14:03:22 UTC (rev 1017) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java 2012-07-17 15:28:11 UTC (rev 1018) @@ -1073,7 +1073,6 @@ try { service.validControl(project); - saveProjectControl(view); JOptionPane.showMessageDialog(view, _("coser.ui.control.controlValidated"), _("coser.ui.control.controlTitle"), JOptionPane.INFORMATION_MESSAGE); } catch (CoserBusinessException ex) { Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java 2012-07-17 14:03:22 UTC (rev 1017) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java 2012-07-17 15:28:11 UTC (rev 1018) @@ -854,14 +854,20 @@ */ public void validSelection(SelectionListsView view) { Selection selection = view.getContextValue(Selection.class); + Project project = view.getContextValue(Project.class); + ProjectService service = view.getContextValue(ProjectService.class); saveSelectionLists(view, selection); boolean canBeValidated = checkSelectionListComments(view, selection); if (canBeValidated) { - selection.setValidated(true); - boolean saved = saveProjectSelection(view); - if (saved) { + try { + service.validSelection(project, selection); JOptionPane.showMessageDialog(view, _("coser.ui.selection.selectionValidated"), - _("coser.ui.selection.selectionTitle"), JOptionPane.INFORMATION_MESSAGE); + _("coser.ui.selection.selectionTitle"), JOptionPane.INFORMATION_MESSAGE); + } catch (CoserBusinessException ex) { + if (log.isErrorEnabled()) { + log.error("Can't save selection", ex); + } + JOptionPane.showMessageDialog(view, ex.getMessage(), _("coser.ui.selection.saveError"), JOptionPane.ERROR_MESSAGE); } } }