Java tutorial
/* * Copyright (c) 2011 by Martin Simons. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package net.lunikon.rethul.web.components; import java.util.Locale; import net.lunikon.rethul.data.StringsDAO; import net.lunikon.rethul.model.File; import net.lunikon.rethul.model.LocalizedString; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.basic.MultiLineLabel; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.TextArea; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.spring.injection.annot.SpringBean; /** * StringEditPanel. * * @author Martin Simons */ public class StringEditPanel extends GenericPanel<LocalizedString> { /** * The stringsDAO. */ @SpringBean private StringsDAO stringsDAO; /** * The fileLocale. */ private Locale fileLocale; /** * The model providing the {@link LocalizedString} to edit. */ private IModel<LocalizedString> stringModel; /** * Constructs a new instance of this class. * * @param id * @param fileLocale * the locale for which the string is translated. */ public StringEditPanel(String id, Locale fileLocale) { super(id); this.fileLocale = fileLocale; build(); } /** * Constructs a new instance of this class. * * @param id * @param fileLocale * the locale for which the string is translated. * @param model * A model containing the MASTER string. */ public StringEditPanel(String id, Locale fileLocale, IModel<LocalizedString> model) { super(id, model); this.fileLocale = fileLocale; build(); } /** * The form holding all components of the editor. */ private Form<LocalizedString> form; private void build() { stringModel = createStringModel(); // form form = new Form<LocalizedString>("form", new CompoundPropertyModel<LocalizedString>(stringModel)) { @Override protected void beforeUpdateFormComponentModels() { if (getModelObject() == null) setModelObject(new LocalizedString()); } @Override protected void onSubmit() { LocalizedString string = getModelObject(); updateLocalizedString(string); } }; add(form); // master information WebMarkupContainer master = new WebMarkupContainer("master"); master.setDefaultModel(new CompoundPropertyModel<LocalizedString>(getModel())); form.add(master); IModel<String> statusModel = new AbstractReadOnlyModel<String>() { @Override public String getObject() { LocalizedString ls = stringModel.getObject(); if (ls == null) return "missing"; return ls.isPending() ? "pending" : "done"; } }; master.add(new Label("key") // .add(new AttributeAppender("class", true, statusModel, " "))); master.add(new MultiLineLabel("translation")); // text area TextArea<String> translation = new TextArea<String>("translation"); translation.setType(String.class); translation.setRequired(true); form.add(translation); // actions form.add(new Button("save") { @Override public void onSubmit() { // in all cases, remove pending-mark form.getModelObject().setPending(false); onSave(); } }); form.add(new Button("savePending") { @Override public void onSubmit() { // mark string as pending form.getModelObject().setPending(true); onSaveAsPending(); } }); // when using the master text, regular form processing has to be // by-passed form.add(new Button("useMaster") { @Override public void onSubmit() { LocalizedString master = StringEditPanel.this.getModelObject(); if (master == null) return; // create new object if doesn't exist LocalizedString string = form.getModelObject(); if (string == null) { string = new LocalizedString(); form.setModelObject(string); } // use text from master to update localized string String translation = master.getTranslation(); string.setTranslation(translation); string.setPending(false); // clear form clear(); onUseMaster(); // update string updateLocalizedString(string); } }.setDefaultFormProcessing(false)); } protected void updateLocalizedString(LocalizedString string) { // complete object when it has been newly created if (string.getId() == null) { LocalizedString master = getModelObject(); if (master == null) return; File file = master.getFile(); String key = master.getKey(); string.setFile(file); string.setKey(key); string.setLocale(getFileLocale()); } stringsDAO.saveOrUpdate(string); onPersisted(); } /** * Called when the string has been updated with the master text. Default * behavior is to just call onSave(). */ protected void onUseMaster() { onSave(); } /** * Called when the string has been marked as pending. */ protected void onSaveAsPending() { // override if required } /** * Called when the string has been saved without it being marked as pending. */ protected void onSave() { // override if required } /** * Called as soon as the changes have been persisted to the database. */ protected void onPersisted() { // override if required } /** * Clears the current input. Use in case the model has changed based on an * event outside of the scope of this component. */ public void clear() { form.clearInput(); } /** * Allows implementing classes to provide an own model for the string to be * edited. The default is a simple {@link LoadableDetachableModel} which * loads the {@link LocalizedString} based on the current master and the * file locale specified. * * @return a model to provide the {@link LocalizedString} the edit functions * will work on. */ protected IModel<LocalizedString> createStringModel() { return new LoadableDetachableModel<LocalizedString>() { @Override protected LocalizedString load() { LocalizedString master = getModelObject(); if (master == null) return null; File file = master.getFile(); String key = master.getKey(); return stringsDAO.get(file, key, getFileLocale()); } }; } /** * Returns the fileLocale. * * @return the fileLocale */ public Locale getFileLocale() { return fileLocale; } /** * Returns the stringModel. * * @return the stringModel */ public IModel<LocalizedString> getStringModel() { return stringModel; } }