/** * MailArchiver is an application that provides services for storing and managing e-mail messages through a Web Services SOAP interface. * Copyright (C) 2012 Marcio Andre Scholl Levien and Fernando Alberto Reuter Wendt and Jose Ronaldo Nogueira Fonseca Junior * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ /******************************************************************************\ * * This product was developed by * * SERVIÇO FEDERAL DE PROCESSAMENTO DE DADOS (SERPRO), * * a government company established under Brazilian law (5.615/70), * at Department of Development of Porto Alegre. * \******************************************************************************/ package serpro.mailarchiver.view.admin; import java.text.DateFormat; import java.util.Date; import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import static com.eventrouter.MessagePublisher.*; import com.eventrouter.annotation.Subscribe; import com.vaadin.data.util.BeanContainer; import com.vaadin.event.Action; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import serpro.mailarchiver.domain.metaarchive.AddressListField; import serpro.mailarchiver.domain.metaarchive.AddressListField_Address; import serpro.mailarchiver.domain.metaarchive.DateTimeField; import serpro.mailarchiver.domain.metaarchive.MailboxListField; import serpro.mailarchiver.domain.metaarchive.MailboxListField_Mailbox; import serpro.mailarchiver.domain.metaarchive.Message; import serpro.mailarchiver.domain.metaarchive.UnstructuredField; import serpro.mailarchiver.service.find.FMessage; import serpro.mailarchiver.util.Logger; import serpro.mailarchiver.util.transaction.WithReadOnlyTx; import serpro.mailarchiver.view.BaseComponent; class Search extends BaseComponent.VerticalLayout { private static final Logger log = Logger.getLocalLogger(); Search() { new SearchController(getDisplayId()); } @Override public final String getDisplayId() { return "search"; } private static final DateFormat dateFormat; static { Locale brazilLocale = Locale.forLanguageTag("pt-BR"); dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM, brazilLocale); } @Autowired private FMessage findMessage; private final BeanContainer container = new BeanContainer(MessageProxy.class); private Table table; private Button search; private final String PATH_PROPERTY = "path"; private final String SUBJECT_PROPERTY = "subject"; private final String DATE_PROPERTY = "date"; private final String SIZE_PROPERTY = "size"; private final String FROM_PROPERTY = "from"; private final String TO_PROPERTY = "to"; private final String CC_PROPERTY = "cc"; private final String BCC_PROPERTY = "bcc"; private final String OID_PROPERTY = "oid"; private static final Action ACTION_OPEN = new Action("Open"); @Subscribe({"/mailarchiver/fill_search_results"}) private void fillSearchResults(String[] oids) { container.removeAllItems(); for(String oid : oids) { container.addItem(oid, new MessageProxy(oid)); } } @Override public void setHeight(float height, int unit) { search.setEnabled(height != 0); super.setHeight(height, unit); } @Override public Search init() { HorizontalLayout hlo = new HorizontalLayout(); hlo.setMargin(true); final TextField queryExpression = new TextField(); queryExpression.setWidth("600px"); queryExpression.setInputPrompt(""); queryExpression.setImmediate(true); hlo.addComponent(queryExpression); search = new Button("Search"); search.setClickShortcut(KeyCode.ENTER); search.addStyleName("primary"); search.addListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { String queryExpr = (String) queryExpression.getValue(); if(!queryExpr.isEmpty()) { publish("/mailarchiver/action/do_search", queryExpression.getValue()); } } }); hlo.addComponent(search); addComponent(hlo); VerticalLayout vlo = new VerticalLayout(); vlo.setMargin(true); table = new ResultsTable("Results:"); table.setWidth("100%"); table.setPageLength(20); table.setImmediate(true); table.setSelectable(true); table.setMultiSelect(false); table.setSortDisabled(true); table.setColumnReorderingAllowed(true); table.setColumnCollapsingAllowed(true); table.setRowHeaderMode(Table.ROW_HEADER_MODE_ICON_ONLY); table.setContainerDataSource(container); fillSearchResults(new String[] {}); table.setVisibleColumns(new Object[] { PATH_PROPERTY, SUBJECT_PROPERTY, DATE_PROPERTY, FROM_PROPERTY, TO_PROPERTY, CC_PROPERTY, BCC_PROPERTY, SIZE_PROPERTY, OID_PROPERTY }); table.setColumnHeader(PATH_PROPERTY, "Pasta"); table.setColumnIcon(PATH_PROPERTY, null); table.setColumnAlignment(PATH_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(PATH_PROPERTY, 0.2f); table.setColumnCollapsed(PATH_PROPERTY, false); table.setColumnHeader(SUBJECT_PROPERTY, "Assunto"); table.setColumnIcon(SUBJECT_PROPERTY, null); table.setColumnAlignment(SUBJECT_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(SUBJECT_PROPERTY, 0.3f); table.setColumnCollapsed(SUBJECT_PROPERTY, false); table.setColumnHeader(DATE_PROPERTY, "Data"); table.setColumnIcon(DATE_PROPERTY, null); table.setColumnAlignment(DATE_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(DATE_PROPERTY, 0.1f); table.setColumnCollapsed(DATE_PROPERTY, false); table.setColumnHeader(SIZE_PROPERTY, "Tamanho"); table.setColumnIcon(SIZE_PROPERTY, null); table.setColumnAlignment(SIZE_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(SIZE_PROPERTY, 0.1f); table.setColumnCollapsed(SIZE_PROPERTY, false); table.setColumnHeader(FROM_PROPERTY, "De"); table.setColumnIcon(FROM_PROPERTY, null); table.setColumnAlignment(FROM_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(FROM_PROPERTY, 0.2f); table.setColumnCollapsed(FROM_PROPERTY, false); table.setColumnHeader(TO_PROPERTY, "Para"); table.setColumnIcon(TO_PROPERTY, null); table.setColumnAlignment(TO_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(TO_PROPERTY, 0.2f); table.setColumnCollapsed(TO_PROPERTY, false); table.setColumnHeader(CC_PROPERTY, "Cópia"); table.setColumnIcon(CC_PROPERTY, null); table.setColumnAlignment(CC_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(CC_PROPERTY, 0.2f); table.setColumnCollapsed(CC_PROPERTY, false); table.setColumnHeader(BCC_PROPERTY, "Cópia oculta"); table.setColumnIcon(BCC_PROPERTY, null); table.setColumnAlignment(BCC_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(BCC_PROPERTY, 0.2f); table.setColumnCollapsed(BCC_PROPERTY, true); table.setColumnHeader(OID_PROPERTY, "ID"); table.setColumnIcon(OID_PROPERTY, null); table.setColumnAlignment(OID_PROPERTY, Table.ALIGN_LEFT); table.setColumnExpandRatio(OID_PROPERTY, 0.2f); table.setColumnCollapsed(OID_PROPERTY, true); /* table.addListener(new Table.ColumnResizeListener() { @Override public void columnResize(ColumnResizeEvent event) { String s = String.format("Results column resize: propertyId=%s currentWidth=%s creviousWidth=%s", event.getPropertyId(), event.getCurrentWidth(), event.getPreviousWidth()); System.out.println(s); } }); table.addListener(new Table.HeaderClickListener() { @Override public void headerClick(HeaderClickEvent event) { String s = String.format("Results header click: propertyId=%s", event.getPropertyId()); System.out.println(s); } }); table.addListener(new ItemClickListener() { @Override public void itemClick(ItemClickEvent event) { String s = String.format("Results item click: itemId=%s propertyId=%s item=%s", event.getItemId(), event.getPropertyId(), event.getItem()); System.out.println(s); } }); table.addListener(new Property.ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { String s = String.format("Results value change: propertyId=%s", event.getProperty()); System.out.println(s); } }); */ vlo.addComponent(table); addComponent(vlo); return this; } @Configurable public class ResultsTable extends Table { public ResultsTable(String caption) { super(caption); } @WithReadOnlyTx @Override protected void refreshRenderedCells() { super.refreshRenderedCells(); } } public class MessageProxy { private String oid; public MessageProxy(String oid) { this.oid = oid; } //-------------------------------------------------------------------------- private boolean messageFetched; private Message message; private void fetchMessageIfNeeded() { if(!messageFetched) { message = findMessage.byId(oid); if(message == null) { log.error("message not found: %s", oid); } messageFetched = true; } } //-------------------------------------------------------------------------- public String getOid() { return oid; } public void setOid(String oid) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean pathFetched; private String path = ""; public String getPath() { if(!pathFetched) { fetchMessageIfNeeded(); if(message == null) { size = "[not found]"; } else { path = message.getFolder().getRelativePath().toString().replace('\\', '/'); } pathFetched = true; } return path; } public void setPath(String path) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean subjectFetched; private String subject = ""; public String getSubject() { if(!subjectFetched) { fetchMessageIfNeeded(); if(message == null) { subject = "[not found]"; } else { UnstructuredField subjectField = message.getSubjectField(); if(subjectField != null) { subject = subjectField.getText(); } } subjectFetched = true; } return subject; } public void setSubject(String subject) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean dateFetched; private String date = ""; public String getDate() { if(!dateFetched) { fetchMessageIfNeeded(); if(message == null) { date = "[not found]"; } else { DateTimeField dateField = message.getDateField(); if(dateField != null) { Date dt = dateField.getDate(); if(dt != null) { date = dateFormat.format(dt); } } } dateFetched = true; } return date; } public void setDate(String date) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean sizeFetched; private String size = ""; public String getSize() { if(!sizeFetched) { fetchMessageIfNeeded(); if(message == null) { size = "[not found]"; } else { size = Integer.toString(message.getSize()); } sizeFetched = true; } return size; } public void setSize(String size) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean fromFetched; private String from = ""; public String getFrom() { if(!fromFetched) { fetchMessageIfNeeded(); if(message == null) { from = "[not found]"; } else { MailboxListField fromField = message.getFromField(); if(fromField != null) { StringBuilder sb = new StringBuilder(); boolean first = true; for(MailboxListField_Mailbox mailbox : fromField.getMailboxList()) { if(first) { first = false; } else { sb.append(", "); } sb.append(mailbox.toDisplayString()); } from = sb.toString(); } } fromFetched = true; } return from; } public void setFrom(String from) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean toFetched; private String to = ""; public String getTo() { if(!toFetched) { fetchMessageIfNeeded(); if(message == null) { to = "[not found]"; } else { AddressListField toField = message.getToField(); if(toField != null) { StringBuilder sb = new StringBuilder(); boolean first = true; for(AddressListField_Address address : toField.getAddressList()) { if(first) { first = false; } else { sb.append(", "); } sb.append(address.toDisplayString()); } to = sb.toString(); } } toFetched = true; } return to; } public void setTo(String to) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean ccFetched; private String cc = ""; public String getCc() { if(!ccFetched) { fetchMessageIfNeeded(); if(message == null) { cc = "[not found]"; } else { AddressListField ccField = message.getCcField(); if(ccField != null) { StringBuilder sb = new StringBuilder(); boolean first = true; for(AddressListField_Address address : ccField.getAddressList()) { if(first) { first = false; } else { sb.append(", "); } sb.append(address.toDisplayString()); } cc = sb.toString(); } } ccFetched = true; } return cc; } public void setCc(String cc) { throw new UnsupportedOperationException(); } //-------------------------------------------------------------------------- private boolean bccFetched; private String bcc = ""; public String getBcc() { if(!bccFetched) { fetchMessageIfNeeded(); if(message == null) { bcc = "[not found]"; } else { AddressListField bccField = message.getBccField(); if(bccField != null) { StringBuilder sb = new StringBuilder(); boolean first = true; for(AddressListField_Address address : bccField.getAddressList()) { if(first) { first = false; } else { sb.append(", "); } sb.append(address.toDisplayString()); } bcc = sb.toString(); } } bccFetched = true; } return bcc; } public void setBcc(String bcc) { throw new UnsupportedOperationException(); } } }