package sushi.application.pages.input; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import sushi.application.components.form.BlockingAjaxButton; import sushi.application.components.form.WarnOnExitForm; import sushi.application.pages.AbstractSushiPage; import sushi.application.pages.main.MainPage; import sushi.csv.importer.CSVImporter; import sushi.event.SushiEvent; import sushi.event.SushiEventType; import sushi.eventhandling.Broker; import sushi.excel.importer.ExcelImporter; import sushi.excel.importer.FileNormalizer; import sushi.excel.importer.SushiImportEvent; public class ExcelEventTypeMatcher extends AbstractSushiPage { private static final long serialVersionUID = 1L; private List<String> columnTitles = new ArrayList<String>(); private FileNormalizer fileNormalizer; private String filePath; private List<Map<String,String>> tableRows = new ArrayList<Map<String,String>>(); private List<String> selectedColumnTitles = new ArrayList<String>(); private List<SushiEventType> selectedEventTypes; private ListView<List<String>> headerContainer; private ListView<Map<String, String>> rowContainer; private WebMarkupContainer tableContainer; private CheckBoxMultipleChoice<SushiEventType> existingTypesCheckBoxMultipleChoice; private DropDownChoice<SushiEventType> eventTypeForPreviewDropDownChoice; private SushiEventType eventTypeForPreview; private Form<Void> layoutForm; public ExcelEventTypeMatcher(PageParameters parameters) { this.filePath = parameters.get("filePath").toString(); int index = filePath.lastIndexOf('.'); String fileExtension = filePath.substring(index + 1, filePath.length()); if (fileExtension.contains("xls")) { fileNormalizer = new ExcelImporter(); } else { fileNormalizer = new CSVImporter(); } columnTitles = fileNormalizer.getColumnTitlesFromFile(filePath); if (!FileUploader.noEventTypesFound(parameters)) { buildMainLayout(); } } private void buildMainLayout() { layoutForm = new WarnOnExitForm("layoutForm"); add(layoutForm); // find matching event types String importTimeName = ExcelEventTypeCreator.GENERATED_TIMESTAMP_COLUMN_NAME; List<SushiEventType> eventTypes = (List<SushiEventType>) SushiEventType.findMatchingEventTypes(columnTitles, importTimeName); if (!eventTypes.isEmpty()) { selectedEventTypes = new ArrayList<SushiEventType>(Arrays.asList(eventTypes.get(0))); eventTypeForPreview = selectedEventTypes.get(0); selectedColumnTitles = eventTypeForPreview.getRootAttributeNames(); } configurePreviewTable(); Button openExcelEventTypeCreatorButton = new Button("openExcelEventTypeCreatorButton") { private static final long serialVersionUID = 1L; @Override public void onSubmit() { PageParameters pageParameters = new PageParameters(); pageParameters.add("filePath", filePath); setResponsePage(ExcelEventTypeCreator.class, pageParameters); } }; layoutForm.add(openExcelEventTypeCreatorButton); existingTypesCheckBoxMultipleChoice = new CheckBoxMultipleChoice<SushiEventType>("existingTypesCheckBoxMultipleChoice", new PropertyModel<ArrayList<SushiEventType>>(this, "selectedEventTypes"), eventTypes); existingTypesCheckBoxMultipleChoice.add(new AjaxFormChoiceComponentUpdatingBehavior() { private static final long serialVersionUID = 1L; @Override protected void onUpdate(AjaxRequestTarget target) { target.add(eventTypeForPreviewDropDownChoice); if (!selectedEventTypes.isEmpty()) { eventTypeForPreview = selectedEventTypes.get(0); updatePreviewTable(target); } } }); layoutForm.add(existingTypesCheckBoxMultipleChoice); eventTypeForPreviewDropDownChoice = new DropDownChoice<SushiEventType>("eventTypeForPreviewDropDownChoice", new PropertyModel<SushiEventType>(this, "eventTypeForPreview"), selectedEventTypes); eventTypeForPreviewDropDownChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") { private static final long serialVersionUID = 1L; @Override protected void onUpdate(AjaxRequestTarget target) { updatePreviewTable(target); } }); eventTypeForPreviewDropDownChoice.setOutputMarkupId(true); layoutForm.add(eventTypeForPreviewDropDownChoice); BlockingAjaxButton addToEventTypeButton = new BlockingAjaxButton("addToEventTypeButton", layoutForm) { private static final long serialVersionUID = 1L; @Override public void onSubmit(AjaxRequestTarget target, Form form) { super.onSubmit(target, form); if (selectedEventTypes.isEmpty()) { getFeedbackPanel().error("Please select at least one event type!"); } else { int eventsCount = 0; for (SushiEventType selectedEventType : selectedEventTypes) { SushiEventType eventType = selectedEventType; String timestamp = eventType.getTimestampName(); List<SushiEvent> events = fileNormalizer.importEventsFromFile(filePath, eventType.getRootLevelValueTypes(), timestamp); for (SushiEvent event : events) { event.setEventType(selectedEventType); } Broker.send(events); eventsCount = events.size(); } String selectedEventTypesString = selectedEventTypes.toString().substring(1, selectedEventTypes.toString().length()-1); PageParameters pageParameters = new PageParameters(); pageParameters.add("successFeedback", eventsCount + " events have been added to " + selectedEventTypesString); setResponsePage(MainPage.class, pageParameters); } } }; layoutForm.add(addToEventTypeButton); } private void updatePreviewTable(AjaxRequestTarget target) { selectedColumnTitles = eventTypeForPreview.getRootAttributeNames(); target.add(tableContainer); } private void configurePreviewTable() { List<SushiImportEvent> events = fileNormalizer.importEventsForPreviewFromFile(filePath, columnTitles); for (SushiImportEvent event : events) { Map<String, String> eventValues = new HashMap<String, String>(); if (event.getTimestamp() != null) { // TODO: another name for key required!!! eventValues.put(event.getExtractedTimestampName(), event.getTimestamp().toString()); } Set<String> attributeNames = event.getValues().keySet(); for (String attributeName : attributeNames) { String attributeValue = event.getValues().get(attributeName).toString(); eventValues.put(attributeName, attributeValue); } eventValues.put(ExcelEventTypeCreator.GENERATED_TIMESTAMP_COLUMN_NAME, event.getImportTime().toString()); tableRows.add(eventValues); } tableContainer = new WebMarkupContainer("tableContainer"); tableContainer.setOutputMarkupId(true); List<String> allColumnTitles = new ArrayList<String>(columnTitles); allColumnTitles.add(ExcelEventTypeCreator.GENERATED_TIMESTAMP_COLUMN_NAME); List<List<String>> headers = new ArrayList<List<String>>(); headers.add(allColumnTitles); headerContainer = new ListView<List<String>>("headerContainer", headers) { private static final long serialVersionUID = 3658948592812295572L; @Override protected void populateItem(ListItem<List<String>> item) { item.add(new ListView<String>("column", selectedColumnTitles) { private static final long serialVersionUID = -3627947713326647386L; @Override protected void populateItem(ListItem<String> item) { item.add(new Label("cell", item.getModelObject())); } }); } }; headerContainer.setOutputMarkupId(true); rowContainer = new ListView<Map<String, String>>("rowContainer", tableRows) { private static final long serialVersionUID = -3353890746328461012L; @Override protected void populateItem(ListItem<Map<String, String>> item) { final Map<String, String> row = item.getModelObject(); item.add(new ListView<String>("column", selectedColumnTitles) { private static final long serialVersionUID = -6270375159398080371L; int i = 0; @Override protected void populateItem(ListItem<String> item) { item.add(new Label("cell", row.get(selectedColumnTitles.get(i++)))); } }); } }; rowContainer.setOutputMarkupId(true); tableContainer.add(headerContainer); tableContainer.add(rowContainer); layoutForm.add(tableContainer); } }