package sushi.application.pages.transformation; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.extensions.markup.html.repeater.tree.AbstractTree; import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; import org.apache.wicket.extensions.markup.html.tabs.ITab; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import sushi.application.components.form.WarnOnExitForm; import sushi.application.components.tree.SushiSelectTree; import sushi.application.components.tree.TreeExpansion; import sushi.application.components.tree.TreeExpansionModel; import sushi.application.components.tree.TreeProvider; import sushi.application.pages.transformation.patternbuilder.AttributeTreePanel; import sushi.application.pages.transformation.patternbuilder.PatternBuilderPanel; import sushi.event.SushiEventType; import sushi.event.collection.SushiTree; import sushi.event.collection.SushiTreeElement; import sushi.transformation.TransformationManager; import sushi.transformation.TransformationRule; import sushi.transformation.collection.SushiPatternTree; import sushi.transformation.element.externalknowledge.ExternalKnowledgeExpressionSet; import com.espertech.esper.client.EPException; import de.agilecoders.wicket.markup.html.bootstrap.tabs.Collapsible; public class AdvancedTransformationRuleEditorPanel extends Panel { private static final long serialVersionUID = -3517674159437927655L; private TextField<String> transformationRuleNameTextField; private String transformationRuleNameFromTree; private Form<Void> layoutForm; private SushiSelectTree<SushiTreeElement<String>> transformationRuleTree; private SushiTree<String> transformationRuleTreeStructure; private TransformationPage transformationPage; private TransformationManager transformationManager; private AdvancedTransformationRuleEditorPanel advancedRuleEditorPanel; protected AttributeTreePanel attributeTreePanel; protected PatternBuilderPanel patternBuilderPanel; public AdvancedTransformationRuleEditorPanel(String id, final TransformationPage transformationPage) { super(id); this.transformationPage = transformationPage; this.transformationManager = transformationPage.getTransformationManager(); this.advancedRuleEditorPanel = this; layoutForm = new WarnOnExitForm("layoutForm"); add(layoutForm); addTabs(); buildTextFields(); buildTransformationRuleTree(); buildButtons(); } private void buildTextFields() { transformationRuleNameTextField = new TextField<String>("transformationRuleNameTextField", new PropertyModel<String>(this, "transformationRuleNameFromTree")); transformationRuleNameTextField.setOutputMarkupId(true); layoutForm.add(transformationRuleNameTextField); } private void buildButtons() { AjaxButton editButton = new AjaxButton("editButton") { private static final long serialVersionUID = 1L; @Override public void onSubmit(AjaxRequestTarget target, Form form) { if (transformationRuleTree.getSelectedElement() != null) { String eventTypeNameFromTree = transformationRuleTree.getSelectedElement().getParent().getValue().toString(); transformationRuleNameFromTree = transformationRuleTree.getSelectedElement().getValue().toString(); TransformationRule transformationRule = TransformationRule.findByEventTypeAndTitle(eventTypeNameFromTree, transformationRuleNameFromTree); patternBuilderPanel.setPatternTree(new SushiPatternTree(transformationRule.getPatternTree().getElements())); patternBuilderPanel.updatePatternTreeTable(target); target.add(transformationRuleNameTextField); SushiEventType selectedEventType = transformationRule.getEventType(); attributeTreePanel.setSelectedEventType(selectedEventType); target.add(attributeTreePanel.getEventTypeDropDownChoice()); attributeTreePanel.updateAttributeTreeTable(target, transformationRule.getAttributeIdentifiersAndExpressions(), transformationRule.getAttributeIdentifiersWithExternalKnowledge()); } } }; layoutForm.add(editButton); // AjaxButton deleteButton = new AjaxButton("deleteButton") { private static final long serialVersionUID = 1L; @Override public void onSubmit(AjaxRequestTarget target, Form form) { if (transformationRuleTree.getSelectedElement() != null) { String eventTypeNameFromTree = transformationRuleTree.getSelectedElement().getParent().getValue().toString(); String transformationRuleNameFromTree = transformationRuleTree.getSelectedElement().getValue().toString(); removeTransformationRule(eventTypeNameFromTree, transformationRuleNameFromTree); renderOrUpdateTransformationRuleTree(); target.add(transformationRuleTree); clearFields(target); } } }; layoutForm.add(deleteButton); AjaxButton saveButton = new AjaxButton("saveButton", layoutForm) { private static final long serialVersionUID = 1L; @Override public void onSubmit(AjaxRequestTarget target, Form form) { SushiEventType selectedEventType = attributeTreePanel.getSelectedEventType(); Map<String, String> attributeIdentifiersAndExpressions = attributeTreePanel.getAttributeIdentifiersAndExpressions(); Map<String, ExternalKnowledgeExpressionSet> attributeIdentifiersWithExternalKnowledge = attributeTreePanel.getAttributeIdentifiersWithExternalKnowledge(); SushiPatternTree patternTree = patternBuilderPanel.getPatternTree(); try { transformationManager.checkForValidity(selectedEventType, transformationRuleNameFromTree, attributeIdentifiersAndExpressions, attributeIdentifiersWithExternalKnowledge, patternTree); saveTransformationRule(target, selectedEventType, transformationRuleNameFromTree, attributeIdentifiersAndExpressions, attributeIdentifiersWithExternalKnowledge, patternTree); clearFields(target); } catch (EPException e) { transformationPage.getFeedbackPanel().error("Transformation rule could not be saved. Please check if you have provided the correct attributes for the pattern and in the attribute selection. Full error message: " + e.getMessage()); target.add(transformationPage.getFeedbackPanel()); } catch (RuntimeException e) { transformationPage.getFeedbackPanel().error(e.getMessage()); target.add(transformationPage.getFeedbackPanel()); } } }; layoutForm.add(saveButton); } private void clearFields(AjaxRequestTarget target) { transformationRuleNameFromTree = ""; target.add(transformationRuleNameTextField); patternBuilderPanel.clear(target); attributeTreePanel.clear(target); } private void saveTransformationRule(AjaxRequestTarget target, SushiEventType selectedEventType, String transformationRuleName, Map<String, String> attributeIdentifiersAndExpressions, Map<String, ExternalKnowledgeExpressionSet> attributeIdentifiersWithExternalKnowledge, SushiPatternTree patternTree) { if (TransformationRule.findByEventTypeAndTitle(selectedEventType.getTypeName(), transformationRuleName) != null) { removeTransformationRule(selectedEventType.getTypeName(), transformationRuleName); } addTransformationRule(selectedEventType, transformationRuleName, attributeIdentifiersAndExpressions, attributeIdentifiersWithExternalKnowledge, patternTree); renderOrUpdateTransformationRuleTree(); target.add(transformationRuleTree); transformationPage.getFeedbackPanel().success("Saved transformation rule '" + transformationRuleName + "' for event type '" + selectedEventType.getTypeName() + "'."); target.add(transformationPage.getFeedbackPanel()); } protected void addTransformationRule(SushiEventType selectedEventType, String transformationRuleName, Map<String, String> attributeIdentifiersAndExpressions, Map<String, ExternalKnowledgeExpressionSet> attributeIdentifiersWithExternalKnowledge, SushiPatternTree patternTree) throws EPException { TransformationRule transformationRule = transformationManager.createTransformationRule(selectedEventType, transformationRuleName, patternTree, attributeIdentifiersAndExpressions, attributeIdentifiersWithExternalKnowledge); transformationManager.register(transformationRule); transformationRule.save(); String eventTypeName = selectedEventType.getTypeName(); addTransformationRuleToTreeStructure(eventTypeName, transformationRuleName); } protected void removeTransformationRule(String eventTypeName, String title) { transformationRuleTreeStructure.removeChild(eventTypeName, title); TransformationRule transformationRule = TransformationRule.findByEventTypeAndTitle(eventTypeName, title); transformationManager.removeFromEsper(transformationRule); transformationRule.remove(); } private void addTransformationRuleToTreeStructure(String eventTypeName, String transformationRuleName) { if (!transformationRuleTreeStructure.containsRootElement(eventTypeName)) { transformationRuleTreeStructure.addRootElement(eventTypeName); } transformationRuleTreeStructure.addChild(eventTypeName, transformationRuleName); } private void buildTransformationRuleTree() { transformationRuleTreeStructure = new SushiTree<String>(); List<TransformationRule> transformationRules = TransformationRule.findAll(); for (TransformationRule transformationRule : transformationRules) { addTransformationRuleToTreeStructure(transformationRule.getEventType().getTypeName(), transformationRule.getTitle()); } renderOrUpdateTransformationRuleTree(); } private void renderOrUpdateTransformationRuleTree() { transformationRuleTree = new SushiSelectTree<SushiTreeElement<String>>("transformationRuleTree", new TreeProvider(generateNodesOfTransformationRuleTree()), new TreeExpansionModel()) { private static final long serialVersionUID = 1L; @Override protected void select(SushiTreeElement<String> element, AbstractTree<SushiTreeElement<String>> tree, final AjaxRequestTarget target) { // only the transformation rules are selectable if (element.hasParent()) { super.select(element, tree, target); } } }; TreeExpansion.get().expandAll(); transformationRuleTree.setOutputMarkupId(true); layoutForm.addOrReplace(transformationRuleTree); } private ArrayList<SushiTreeElement<String>> generateNodesOfTransformationRuleTree() { ArrayList<SushiTreeElement<String>> treeElements = new ArrayList<SushiTreeElement<String>>(); List<String> eventTypes = transformationRuleTreeStructure.getRootElements(); for (String eventType : eventTypes) { SushiTreeElement<String> rootElement = new SushiTreeElement<String>(eventType); treeElements.add(rootElement); if (transformationRuleTreeStructure.hasChildren(eventType)) { fillTreeLevel(rootElement, transformationRuleTreeStructure.getChildren(eventType), transformationRuleTreeStructure); } } return treeElements; } private void fillTreeLevel(SushiTreeElement<String> parent, List<String> children, SushiTree<String> transformationRuleTreeStructure) { for (String newValue : children) { SushiTreeElement<String> newElement = new SushiTreeElement<String>(parent, newValue.toString()); if (transformationRuleTreeStructure.hasChildren(newValue)) { fillTreeLevel(newElement, transformationRuleTreeStructure.getChildren(newValue), transformationRuleTreeStructure); } } } private void addTabs() { List<ITab> tabs = new ArrayList<ITab>(); tabs.add(new AbstractTab(new Model<String>("Build pattern")) { public Panel getPanel(String panelId) { patternBuilderPanel = new PatternBuilderPanel(panelId, advancedRuleEditorPanel); return patternBuilderPanel; } }); tabs.add(new AbstractTab(new Model<String>("Select attribute values")) { public Panel getPanel(String panelId) { attributeTreePanel = new AttributeTreePanel(panelId, advancedRuleEditorPanel); return attributeTreePanel; } }); layoutForm.add(new Collapsible("collapsible", tabs, Model.of(-1))); } public AttributeTreePanel getAttributeTreePanel() { return attributeTreePanel; } public PatternBuilderPanel getPatternBuilderPanel() { return patternBuilderPanel; } public TransformationPage getTransformationPage() { return transformationPage; } }