package ro.nextreports.server.web.analysis.feature.create; import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.ChoiceRenderer; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.TextArea; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.image.ContextImage; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.spring.injection.annot.SpringBean; import ro.nextreports.server.domain.Analysis; import ro.nextreports.server.domain.AnalysisDeclaredColumn; import ro.nextreports.server.service.StorageService; import ro.nextreports.server.util.AnalysisUtil; import ro.nextreports.server.web.analysis.util.DatabaseUtil; import ro.nextreports.server.web.common.behavior.SimpleTooltipBehavior; import ro.nextreports.server.web.common.form.FormContentPanel; import ro.nextreports.server.web.common.form.FormPanel; import ro.nextreports.server.web.common.table.BaseTable; import ro.nextreports.server.web.common.table.LinkPropertyColumn; import ro.nextreports.server.web.core.validation.AnalysisNameValidator; public class CreatePanel extends FormContentPanel<Analysis> { private AnalysisDeclaredColumn declaredColumnObject; private IModel<Analysis> model; private Label label; private DataTable<AnalysisDeclaredColumn, String> table; private DeclaredColumnObjectDataProvider provider; private TextField<String> nameText; private TextArea<String> expressionText; private DropDownChoice<String> typeChoice; private String selectedColumn; private String selectedAgg; private int editIndex = -1; private int oldColumnIndex = -1; private int oldFilterIndex = -1; private int oldSortIndex = -1; private int oldGroupIndex = -1; private IModel<String> addTextModel; @SpringBean private StorageService storageService; public CreatePanel(IModel<Analysis> model) { super(FormPanel.CONTENT_ID); this.model = model; ContextImage urlImage = new ContextImage("infoImage","images/information.png"); urlImage.add(new SimpleTooltipBehavior(AnalysisUtil.getAnalysisInfo(model.getObject(), 5, storageService.getSettings()))); add(urlImage); declaredColumnObject = new AnalysisDeclaredColumn(); declaredColumnObject.setType("java.lang.String"); declaredColumnObject.setName(UUID.randomUUID().toString()); selectedColumn = model.getObject().getColumns().get(0); add(new Label("name", new StringResourceModel("CreatePanel.name", this, null))); nameText = new TextField<String>("nameText", new PropertyModel<String>(this, "declaredColumnObject.columnName")); nameText.add(new AnalysisNameValidator(getString("JcrNameValidator"))); nameText.setOutputMarkupPlaceholderTag(true); add(nameText); DropDownChoice<String> columnChoice = new DropDownChoice<String>("columnChoice", new PropertyModel<String>(this, "selectedColumn"), model.getObject().getColumns()); columnChoice.setOutputMarkupPlaceholderTag(true); columnChoice.setNullValid(false); columnChoice.add(new AjaxFormComponentUpdatingBehavior("onChange") { @Override protected void onUpdate(AjaxRequestTarget target) { selectedColumn = (String) getFormComponent().getConvertedInput(); } }); add(columnChoice); final DropDownChoice<String> aggChoice = new DropDownChoice<String>("aggChoice", new PropertyModel<String>(this, "selectedAgg"), DatabaseUtil.aggregates); aggChoice.setOutputMarkupPlaceholderTag(true); aggChoice.setNullValid(true); // needed for addColumn AjaxLink aggChoice.add(new AjaxFormComponentUpdatingBehavior("onChange") { @Override protected void onUpdate(AjaxRequestTarget target) { selectedAgg = (String) getFormComponent().getConvertedInput(); } }); add(aggChoice); AjaxLink addColumn = new AjaxLink("addColumn") { @Override public void onClick(AjaxRequestTarget target) { String newText = declaredColumnObject.getExpression(); if (newText == null) { newText = ""; } if (selectedAgg == null) { newText = newText + " " + selectedColumn; } else { newText = newText + " " + selectedAgg + "(" + selectedColumn + ")"; } declaredColumnObject.setExpression(newText); target.add(expressionText); } }; add(addColumn); add(new Label("expression", new StringResourceModel("CreatePanel.expression", this, null))); expressionText = new TextArea<String>("expressionText", new PropertyModel<String>(this, "declaredColumnObject.expression")); //expressionText.add(new JcrNameValidator(getString("JcrNameValidator"))); expressionText.setOutputMarkupPlaceholderTag(true); add(expressionText); add(new Label("type", new StringResourceModel("CreatePanel.type", this, null))); typeChoice = new DropDownChoice<String>("typeChoice", new PropertyModel<String>(this, "declaredColumnObject.type"), DatabaseUtil.getJavaTypes(), new ChoiceRenderer<String>() { @Override public Object getDisplayValue(String name) { int index = name.lastIndexOf("."); return name.substring(index+1); } } ); typeChoice.setOutputMarkupPlaceholderTag(true); typeChoice.setNullValid(false); add(typeChoice); AjaxSubmitLink addLink = new AjaxSubmitLink("addLink") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { if ((declaredColumnObject.getColumnName() == null) || "".equals(declaredColumnObject.getColumnName().trim())) { error(getString("CreatePanel.askName")); target.add(getFeedbackPanel()); return; } if ((declaredColumnObject.getExpression() == null) || "".equals(declaredColumnObject.getExpression().trim())) { error(getString("CreatePanel.askExpression")); target.add(getFeedbackPanel()); return; } if (editIndex != -1) { int index = findDeclaredColumnByName(CreatePanel.this.model.getObject().getDeclaredColumns(), declaredColumnObject.getColumnName()); if ( (index != -1) && (index != editIndex) ) { error(getString("CreatePanel.duplicateColumn")); target.add(getFeedbackPanel()); return; } CreatePanel.this.model.getObject().editDeclaredColumn(editIndex, oldColumnIndex, oldFilterIndex, oldSortIndex, oldGroupIndex, declaredColumnObject.clone()); resetEdit(target); } else { int index = findDeclaredColumnByName(CreatePanel.this.model.getObject().getDeclaredColumns(), declaredColumnObject.getColumnName()); if (index != -1) { error(getString("CreatePanel.duplicateColumn")); target.add(getFeedbackPanel()); return; } CreatePanel.this.model.getObject().addDeclaredColumn(declaredColumnObject.clone()); } target.add(getFeedbackPanel()); target.add(table); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(getFeedbackPanel()); } }; addTextModel = Model.of(""); label = new Label("addMessage", addTextModel); label.setOutputMarkupPlaceholderTag(true); addLink.add(label); add(addLink); addTable(); } protected void cancelAdd() { if (declaredColumnObject != null) { CreatePanel.this.model.getObject().deleteDeclaredColumn(declaredColumnObject); } } protected void onConfigure() { super.onConfigure(); addTextModel.setObject(getString("add")); } private void resetEdit(AjaxRequestTarget target) { addTextModel.setObject(getString("add")); editIndex = -1; oldColumnIndex = -1; oldFilterIndex = -1; oldSortIndex = -1; oldGroupIndex = -1; target.add(label); } private void addTable() { List<IColumn<AnalysisDeclaredColumn, String>> columns = new ArrayList<IColumn<AnalysisDeclaredColumn, String>>(); columns.add(new AbstractColumn<AnalysisDeclaredColumn, String>(new Model<String>("")) { @Override public String getCssClass() { return "index"; } public void populateItem(Item<ICellPopulator<AnalysisDeclaredColumn>> item, String componentId, final IModel<AnalysisDeclaredColumn> rowModel) { int col=item.getIndex(); Item<?> i = (Item<?>) item.getParent().getParent(); int row = i.getIndex()+1; item.add(new Label(componentId, new Model<String>(String.valueOf(row)))); } }); columns.add(new AbstractColumn<AnalysisDeclaredColumn, String>(new StringResourceModel("CreatePanel.name", CreatePanel.this, null)) { public void populateItem(Item<ICellPopulator<AnalysisDeclaredColumn>> item, String componentId, final IModel<AnalysisDeclaredColumn> rowModel) { final AnalysisDeclaredColumn createObject = rowModel.getObject(); item.add(new Label(componentId, new Model<String>(createObject.getColumnName()))); } }); columns.add(new AbstractColumn<AnalysisDeclaredColumn, String>(new StringResourceModel("CreatePanel.expression", CreatePanel.this, null)) { public void populateItem(Item<ICellPopulator<AnalysisDeclaredColumn>> item, String componentId, final IModel<AnalysisDeclaredColumn> rowModel) { final AnalysisDeclaredColumn createObject = rowModel.getObject(); item.add(new Label(componentId, new Model<String>(createObject.getExpression()))); } }); columns.add(new AbstractColumn<AnalysisDeclaredColumn, String>(new StringResourceModel("CreatePanel.type", CreatePanel.this, null)) { public void populateItem(Item<ICellPopulator<AnalysisDeclaredColumn>> item, String componentId, final IModel<AnalysisDeclaredColumn> rowModel) { final AnalysisDeclaredColumn createObject = rowModel.getObject(); String type = createObject.getType(); int index = type.lastIndexOf("."); item.add(new Label(componentId, new Model<String>(type.substring(index+1)))); } }); columns.add(new LinkPropertyColumn<AnalysisDeclaredColumn>(new StringResourceModel("edit", CreatePanel.this, null), new StringResourceModel("edit", CreatePanel.this, null)) { private static final long serialVersionUID = 1L; @Override public void onClick(Item item, String componentId, IModel model, AjaxRequestTarget target) { AnalysisDeclaredColumn declaredColumnObject = (AnalysisDeclaredColumn) model.getObject(); editIndex = CreatePanel.this.model.getObject().getDeclaredColumns().indexOf(declaredColumnObject); oldColumnIndex = CreatePanel.this.model.getObject().getColumnIndexByName(declaredColumnObject.getExpression() + DatabaseUtil.AS + declaredColumnObject.getColumnName()); oldFilterIndex = CreatePanel.this.model.getObject().getFilterIndexByName(declaredColumnObject.getColumnName()); oldSortIndex = CreatePanel.this.model.getObject().getSortIndexByName(declaredColumnObject.getColumnName()); oldGroupIndex = CreatePanel.this.model.getObject().getGroupIndexByName(declaredColumnObject.getColumnName()); CreatePanel.this.declaredColumnObject = declaredColumnObject; addTextModel.setObject(getString("edit")); target.add(nameText); target.add(expressionText); target.add(typeChoice); target.add(label); } }); columns.add(new LinkPropertyColumn<AnalysisDeclaredColumn>(new StringResourceModel("delete", CreatePanel.this, null), new StringResourceModel("delete", CreatePanel.this, null), new StringResourceModel("CreatePanel.askDelete", CreatePanel.this, null)) { private static final long serialVersionUID = 1L; @Override public void onClick(Item item, String componentId, IModel model, AjaxRequestTarget target) { AnalysisDeclaredColumn declaredColumnObject = (AnalysisDeclaredColumn) model.getObject(); CreatePanel.this.model.getObject().deleteDeclaredColumn(declaredColumnObject); resetEdit(target); target.add(table); onDelete(getAnalysis(), target); } }); provider = new DeclaredColumnObjectDataProvider(model); table = new BaseTable<AnalysisDeclaredColumn>("table", columns, provider, 10); table.setOutputMarkupId(true); add(table); } public AnalysisDeclaredColumn getDeclaredColumnObject() { return declaredColumnObject; } public Analysis getAnalysis() { return CreatePanel.this.model.getObject(); } public void onDelete(Analysis analysis, AjaxRequestTarget target) { } private int findDeclaredColumnByName(List<AnalysisDeclaredColumn> list, String columnName) { for (int i=0, size=list.size(); i<size; i++) { if (list.get(i).getColumnName().equals(columnName)) { return i; } } return -1; } public boolean isEdit() { return editIndex != -1; } }