/* * codjo.net * * Common Apache License 2.0 */ package net.codjo.broadcast.server; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import net.codjo.broadcast.common.BroadcastException; import net.codjo.broadcast.common.Broadcaster; import net.codjo.broadcast.common.ConnectionProvider; import net.codjo.broadcast.common.Context; import net.codjo.broadcast.common.DiffuserContextAdapter; import net.codjo.broadcast.common.PostBroadcaster; import net.codjo.broadcast.common.diffuser.Diffuser; import net.codjo.broadcast.common.diffuser.DiffuserException; import net.codjo.util.file.FileUtil; import org.apache.log4j.Logger; /** * G�n�re et diffuse un fichier. */ class DefaultBroadcaster implements Broadcaster { private static final Logger APP = Logger.getLogger(DefaultBroadcaster.class); private ConnectionProvider connectionProvider = null; private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); private File destinationFileTemplate; private Diffuser diffuser; private FileGenerator fileGenerator; private boolean historiseFile = false; private List<PostBroadcaster> postBroadcasterList = new ArrayList<PostBroadcaster>(); private Context rootContext; DefaultBroadcaster(Context rootContext, FileGenerator fileGenerator, File destinationFile, Diffuser diffuser, ConnectionProvider connectionProvider) { if (fileGenerator == null || destinationFile == null) { throw new IllegalArgumentException(); } this.diffuser = diffuser; this.fileGenerator = fileGenerator; setDestinationFile(destinationFile); this.rootContext = rootContext; this.connectionProvider = connectionProvider; } public void broadcast(Context currentContext) throws IOException, SQLException, BroadcastException { currentContext.connectTo(rootContext); Connection connection = connectionProvider.getConnection(); String databaseUserName = connection.getMetaData().getUserName(); if (databaseUserName != null) { currentContext.putParameter("dbApplicationUser", databaseUserName); } File tmpFile = null; try { tmpFile = fileGenerator.generate(currentContext, connection); if (tmpFile == null) { return; } File generatedFile = moveToDestination(currentContext, tmpFile); executeAllPostBroadcaster(currentContext, generatedFile, connection); executeDiffuser(currentContext, generatedFile); } finally { cleanUp(connection, tmpFile); } } public File getDestinationFile(Context ctxt) { return ctxt.replaceVariables(destinationFileTemplate); } public Diffuser getDiffuser() { return diffuser; } public void setDestinationFile(File destFile) { this.destinationFileTemplate = destFile; } public void setDiffuser(Diffuser diffuser) { this.diffuser = diffuser; } /** * Positionne l'attribut historiseFile de DefaultBroadcaster * * @param newHistoriseFile La nouvelle valeur de historiseFile */ public void setHistoriseFile(boolean newHistoriseFile) { historiseFile = newHistoriseFile; } /** * Positionne l'attribut postBroadcaster de DefaultBroadcaster * * @param pbList La nouvelle valeur de postBroadcaster * * @throws NullPointerException pbList n'est pas definit */ public void setPostBroadcaster(List<PostBroadcaster> pbList) { if (pbList == null) { throw new NullPointerException(); } postBroadcasterList = new ArrayList<PostBroadcaster>(pbList); } String realDestinationFileName(File destinationFile) { if (historiseFile) { String fileName = destinationFile.getName(); int insertPos = fileName.indexOf("."); if (insertPos == -1) { insertPos = fileName.length(); } return fileName.substring(0, insertPos) + "_" + dateFormat.format(new java.util.Date()) + fileName.substring(insertPos, fileName.length()); } else { return destinationFile.getName(); } } private void cancelPostBroadcast(List<PostBroadcaster> executedPostList, Context currentCtxt, Connection con) { for (Object anExecutedPostList : executedPostList) { PostBroadcaster post = (PostBroadcaster)anExecutedPostList; try { post.undoProceed(currentCtxt, con); } catch (Exception exception) { APP.error(exception); } } } private void executeAllPostBroadcaster(Context currentCtxt, File generatedFile, Connection connection) throws SQLException, BroadcastException { if (postBroadcasterList.isEmpty()) { return; } List<PostBroadcaster> executedPostList = new ArrayList<PostBroadcaster>(); try { for (PostBroadcaster postBroadcaster : postBroadcasterList) { postBroadcaster.proceed(currentCtxt, connection); executedPostList.add(postBroadcaster); } } catch (Exception exception) { APP.error(exception); generatedFile.delete(); cancelPostBroadcast(executedPostList, currentCtxt, connection); throw new BroadcastException("Erreur durant les post-traitements " + "de diffusion : La diffusion est annul�e", exception); } } private void executeDiffuser(Context currentContext, File generatedFile) throws BroadcastException { if (diffuser == null) { return; } try { diffuser.diffuse(new DiffuserContextAdapter(currentContext), generatedFile); } catch (DiffuserException ex) { throw new BroadcastException(ex); } } /** * Deplace le fichier genere dans le repertoire destination (avec historisation). * * @return Le fichier deplac� * * @throws IOException Impossible de deplacer (ou historiser) le fichier * @see net.codjo.util.file.FileUtil#moveFileTo */ private File moveToDestination(Context ctxt, File generatedFile) throws IOException { File destinationFile = getDestinationFile(ctxt); File tmp = new File(generatedFile.getParent(), realDestinationFileName(destinationFile)); tmp.delete(); boolean state = generatedFile.renameTo(tmp); if (!state) { APP.debug("Impossible de renommer le fichier " + generatedFile); APP.debug(" en " + tmp); APP.debug("source exists ? " + generatedFile.exists()); APP.debug("destination exists ? " + tmp.exists()); generatedFile.delete(); throw new IOException("Impossible de renommer le fichier " + generatedFile); } try { return FileUtil.moveFileTo(destinationFile.getParent(), tmp, historiseFile); } catch (IOException ioe) { tmp.delete(); throw ioe; } } private void cleanUp(Connection connection, File tmpFile) throws SQLException { try { if (tmpFile != null) { tmpFile.delete(); } } finally { connectionProvider.releaseConnection(connection); } } }