Java tutorial
/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.brixcms.plugin.site.page.admin; import com.inmethod.grid.IDataSource; import com.inmethod.grid.IGridColumn; import com.inmethod.grid.SizeUnit; import com.inmethod.grid.column.CheckBoxColumn; import com.inmethod.grid.column.PropertyColumn; import com.inmethod.grid.column.editable.EditablePropertyColumn; import com.inmethod.grid.column.editable.SubmitCancelColumn; import com.inmethod.grid.datagrid.DataGrid; import com.inmethod.grid.datagrid.DefaultDataGrid; 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.AjaxButton; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.util.lang.Objects; import org.apache.wicket.validation.IValidatable; import org.apache.wicket.validation.IValidator; import org.apache.wicket.validation.ValidationError; import org.brixcms.jcr.wrapper.BrixNode; import org.brixcms.plugin.site.page.AbstractContainer; import org.brixcms.plugin.site.page.global.GlobalContainerNode; import org.brixcms.web.generic.BrixGenericPanel; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class VariablesPanel extends BrixGenericPanel<BrixNode> { private AjaxLink<?> delete; public VariablesPanel(String id, IModel<BrixNode> model) { super(id, model); List<IGridColumn<IDataSource<BrixNode>, BrixNode>> columns = new ArrayList<IGridColumn<IDataSource<BrixNode>, BrixNode>>(); columns.add(new CheckBoxColumn<IDataSource<BrixNode>, BrixNode>("checkbox")); columns.add(new PropertyColumn<IDataSource<BrixNode>, BrixNode, String>(new ResourceModel("key"), "key")); columns.add(new EditablePropertyColumn<IDataSource<BrixNode>, BrixNode, String>(new ResourceModel("value"), "value") { @Override protected void addValidators(FormComponent component) { component.setRequired(true); } }); columns.add( new SubmitCancelColumn<IDataSource<BrixNode>, BrixNode>("submitcancel", new ResourceModel("edit")) { @Override protected void onError(AjaxRequestTarget target, IModel rowModel, WebMarkupContainer rowComponent) { target.addChildren(VariablesPanel.this, FeedbackPanel.class); } @Override protected void onSubmitted(AjaxRequestTarget target, IModel<BrixNode> rowModel, WebMarkupContainer rowComponent) { target.addChildren(VariablesPanel.this, FeedbackPanel.class); super.onSubmitted(target, rowModel, rowComponent); } }); final DataGrid<BrixNode> grid = new DefaultDataGrid<BrixNode>("grid", new Model(new DataSource()), columns) { @Override public void onItemSelectionChanged(IModel<BrixNode> item, boolean newValue) { AjaxRequestTarget target = AjaxRequestTarget.get(); if (target != null) { target.addComponent(delete); } super.onItemSelectionChanged(item, newValue); } }; add(grid); grid.setSelectToEdit(false); grid.setClickRowToSelect(true); grid.setContentHeight(17, SizeUnit.EM); add(delete = new AjaxLink<Void>("deleteSelected") { @Override public void onClick(AjaxRequestTarget target) { AbstractContainer node = (AbstractContainer) VariablesPanel.this.getModelObject(); for (IModel<?> m : grid.getSelectedItems()) { Entry e = (Entry) m.getObject(); node.setVariableValue(e.getKey(), null); } node.save(); grid.markAllItemsDirty(); grid.update(); grid.resetSelectedItems(); target.addComponent(this); } @Override public boolean isEnabled() { return grid.getSelectedItems().isEmpty() == false; } }); delete.setOutputMarkupId(true); add(new InsertForm("form") { @Override protected void onItemAdded() { grid.markAllItemsDirty(); grid.update(); } }); add(new FeedbackPanel("feedback").setOutputMarkupId(true)); } private class DataSource implements IDataSource<Entry> { public IModel<Entry> model(Entry object) { return new Model<Entry>(object); } public void query(IQuery query, IQueryResult<Entry> result) { AbstractContainer node = (AbstractContainer) VariablesPanel.this.getModelObject(); List<Entry> res = new ArrayList<Entry>(); for (String s : node.getSavedVariableKeys()) { res.add(new Entry(s)); } Collections.sort(res, new Comparator<Entry>() { public int compare(Entry o1, Entry o2) { return o1.getKey().compareTo(o2.getKey()); } }); int total = res.size(); if (total > query.getFrom()) { res = res.subList(query.getFrom(), total); } result.setItems(res.iterator()); result.setTotalCount(total); } public void detach() { } } private class Entry implements Serializable { private final String key; public Entry(String key) { this.key = key; } public String getKey() { return key; } public String getValue() { AbstractContainer node = (AbstractContainer) VariablesPanel.this.getModelObject(); return node.getVariableValue(key, false); } public void setValue(String value) { AbstractContainer node = (AbstractContainer) VariablesPanel.this.getModelObject(); node.setVariableValue(key, value); node.save(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof Entry == false) { return false; } Entry that = (Entry) obj; return Objects.equal(key, that.key); } @Override public int hashCode() { return Objects.hashCode(key); } } private abstract class InsertForm extends Form<Void> { public InsertForm(String id) { super(id); IModel<List<? extends String>> choicesModel = new LoadableDetachableModel<List<? extends String>>() { @Override protected List<? extends String> load() { List<String> result = new ArrayList<String>(); AbstractContainer node = (AbstractContainer) VariablesPanel.this.getModelObject(); result.addAll(node.getVariableKeys()); return result; } }; final TextField<String> tf; add(tf = new TextField<String>("key", new PropertyModel<String>(this, "key"))); tf.setRequired(true); tf.setOutputMarkupId(true); final DropDownChoice<String> keySuggestions; add(keySuggestions = new DropDownChoice<String>("keySuggestions", new Model<String>(), choicesModel) { @Override public boolean isVisible() { return VariablesPanel.this.getModelObject() instanceof GlobalContainerNode == false; } }); keySuggestions.setNullValid(true); keySuggestions.add(new AjaxFormComponentUpdatingBehavior("onchange") { @Override protected void onUpdate(AjaxRequestTarget target) { tf.setModelObject(keySuggestions.getModelObject()); keySuggestions.setModelObject(null); target.addComponent(tf); target.addComponent(keySuggestions); target.focusComponent(tf); } }); add(new TextField<String>("value", new PropertyModel<String>(this, "value")).setRequired(true)); add(new AjaxButton("submit") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { AbstractContainer node = (AbstractContainer) VariablesPanel.this.getModelObject(); node.setVariableValue(key, value); node.save(); onItemAdded(); key = null; value = null; target.addComponent(form); target.addChildren(findParent(VariablesPanel.class), FeedbackPanel.class); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.addChildren(findParent(VariablesPanel.class), FeedbackPanel.class); } }); tf.add(new IValidator<String>() { public void validate(IValidatable validatable) { String key = (String) validatable.getValue(); AbstractContainer node = (AbstractContainer) VariablesPanel.this.getModelObject(); if (key.contains("/") || key.contains(":")) { report(validatable, "keyValidator.invalidKey", key); } else if (node.getVariableValue(key, false) != null) { report(validatable, "keyValidator.duplicateKey", key); } } private void report(IValidatable validatable, String messageKey, String key) { validatable.error(new ValidationError().addMessageKey(messageKey).setVariable("key", key)); } }); } private String key; private String value; abstract protected void onItemAdded(); } }