package au.com.vaadinutils.wizards.bulkJasperEmail; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import net.sf.jasperreports.engine.JRException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.vaadin.teemu.wizards.WizardStep; import au.com.vaadinutils.crud.CrudEntity; import au.com.vaadinutils.fields.PoJoTable; import au.com.vaadinutils.ui.WorkingDialog; import au.com.vaadinutils.util.MutableInteger; import au.com.vaadinutils.util.ProgressBarWorker; import au.com.vaadinutils.util.ProgressTaskListener; import au.com.vaadinutils.util.VUNotification; import com.vaadin.addon.jpacontainer.JPAContainer; import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.ProgressBar; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; public class ShowProgressStep<C extends CrudEntity> implements WizardStep, ProgressTaskListener<JasperTransmission> { static private transient Logger logger = LogManager.getLogger(ShowProgressStep.class); JPAContainer<C> entities; private WizardView<?, ?, ?> wizardView; private boolean sendComplete = false; private ProgressBar indicator; private Label progressDescription; private PoJoTable<JasperTransmission> progressTable; private MutableInteger queued = new MutableInteger(0); private MutableInteger rejected = new MutableInteger(0); private WorkingDialog workDialog; public ShowProgressStep(WizardView<?, ?, ?> wizardView) { this.wizardView = wizardView; } @Override public String getCaption() { return "Send Messages"; } @Override public Component getContent() { VerticalLayout layout = new VerticalLayout(); layout.setSizeFull(); progressTable = new PoJoTable<JasperTransmission>(JasperTransmission.class, new String[] { "Description", "RecipientEmailAddress", "Exception" }); progressTable.setColumnWidth("Description", 80); progressTable.setColumnWidth("RecipientEmailAddress", 100); progressTable.setColumnExpandRatio("Exception", 1); progressTable.setSizeFull(); progressDescription = new Label(); layout.addComponent(progressDescription); layout.setMargin(true); indicator = new ProgressBar(new Float(0.0)); indicator.setHeight("30px"); indicator.setIndeterminate(false); indicator.setImmediate(true); indicator.setSizeFull(); layout.addComponent(indicator); layout.addComponent(this.progressTable); layout.setExpandRatio(progressTable, 1); Collection<?> recipients = wizardView.getRecipientStep().getRecipientIds(); ArrayList<JasperTransmission> transmissions = new ArrayList<JasperTransmission>(); HashSet<String> dedupList = new HashSet<String>(); JasperProxy proxy; try { proxy = wizardView.getJasperProxy(); } catch (JRException e) { logger.error(e, e); VUNotification.show(e, Type.ERROR_MESSAGE); throw new RuntimeException(e); } for (Object recipientId : recipients) { Recipient recipient = this.wizardView.getRecipient((Long) recipientId); // Find if the recipient has ane email address String email = recipient.getEmailAddress(); if (email != null && email.length() > 0) { queueTransmission(transmissions, dedupList, recipient, email, proxy); continue; } // No email address found JasperTransmission transmission = new JasperTransmission(recipient, proxy, new RecipientException( "No email address on recipient.", recipient)); ShowProgressStep.this.progressTable.addRow(transmission); rejected.setValue(rejected.intValue() + 1); } if (transmissions.size() == 0) { Notification.show("None of the selected recipients have an Email address", Type.ERROR_MESSAGE); } else { queued.setValue(transmissions.size()); progressDescription.setValue(queued.intValue() + " messages queued."); SendEmailTask task = new SendEmailTask(this, proxy, transmissions); workDialog = new WorkingDialog("Sending Emails", "Sending...", task); ProgressBarWorker<JasperTransmission> worker = new ProgressBarWorker<JasperTransmission>(task); worker.start(); UI.getCurrent().addWindow(workDialog); } return layout; } private void queueTransmission(ArrayList<JasperTransmission> transmissions, HashSet<String> dedupList, Recipient recipient, String toEmailAddress, JasperProxy proxy) { JasperTransmission transmission = new JasperTransmission(recipient); if (!dedupList.contains(toEmailAddress)) { dedupList.add(toEmailAddress); transmissions.add(transmission); } else { transmission.setException(new RecipientException("Duplicate email address.", recipient)); ShowProgressStep.this.progressTable.addRow(transmission); } } @Override public boolean onAdvance() { return sendComplete; } @Override public boolean onBack() { return true; } /** * you better get a lock on the UI before calling this method! */ public final void taskProgress(final int count, final int max, final JasperTransmission status) { UI ui = UI.getCurrent(); if (ui == null) { throw new RuntimeException("You appear to be calling from a worker thread, no UI is available"); } if (!ui.isAttached()) { logger.warn("The UI is nolonger attached, cant deliver message to user"); } String message = "Sending: " + count + " of " + max + " messages."; progressDescription.setValue(message); indicator.setValue((float) count / max); workDialog.progress(count, max, message); ShowProgressStep.this.progressTable.addRow(status); } public final void taskComplete(final int sent) { UI ui = UI.getCurrent(); if (ui == null) { throw new RuntimeException("You appear to be calling from a worker thread, no UI is available"); } if (!ui.isAttached()) { logger.warn("The UI is nolonger attached, cant deliver message to user"); } sendComplete = true; indicator.setValue(1.0f); if (ShowProgressStep.this.rejected.intValue() == 0 && queued.intValue() == sent) progressDescription.setValue("All Email Messages have been sent successfully."); else progressDescription.setValue(sent + " Email Message " + (sent == 1 ? "has" : "s have") + " been sent successfully. Check the list below for the reason why some of the messages failed."); VUNotification.show("Email batch send complete", Type.TRAY_NOTIFICATION); workDialog.complete(sent); } @Override public void taskItemError(JasperTransmission transmission) { this.progressTable.addRow(transmission); } @Override public void taskException(Exception e) { Notification.show("Error occurred sending Message.", e.getMessage(), Type.ERROR_MESSAGE); } }