/**
* 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();
}
}
}