/*
* Copyright (C) 2012 Jan Pokorsky
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cz.cas.lib.proarc.webapp.client.action;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import cz.cas.lib.proarc.webapp.client.ClientMessages;
/**
* Helper class providing description for subclasses that saves some content.
*
* @author Jan Pokorsky
*/
public abstract class SaveAction extends AbstractAction {
public SaveAction(ClientMessages i18n) {
super(i18n.SaveAction_Title(),
"[SKIN]/actions/save.png",
i18n.SaveAction_Hint());
}
/**
* Saves savable object.
*
<pre><code>
ask strategy states
T ASK validate, (IfValidAsk, IfYesSave | IfNoDone) | (IfInvalidAsk, IfReallyYesSave | IfNoDone)
T IGNORE ask, (IfYesSave | IfNoDone)
T RUN validate, (IfValidAsk, IfYesSave | IfNoDone) | IfInvalidDone
F ASK validate, IfValidSave | (IfInvalidAsk, IfYesSave | IfNoDone)
F IGNORE save
F RUN validate, IfValidSave | IfInvalidDone
</code></pre>
*
* @param savable object implementing save
* @param saveCallback listener to get save result
* @param ask ask user before the save
* @param strategy validation strategy
*/
public static void saveTask(Savable savable, BooleanCallback saveCallback,
boolean ask, SaveValidation strategy, ClientMessages i18n) {
BooleanCallback saveIfYes = new SaveIfYes(savable, saveCallback);
BooleanCallback runIfValid = getRunIfValid(savable, saveCallback, ask,
saveIfYes, strategy, i18n);
if (strategy == SaveValidation.IGNORE) {
if (ask) {
askSave(saveIfYes, i18n);
} else {
savable.save(saveCallback);
}
} else {
savable.validate(runIfValid);
}
}
private static void askSave(final BooleanCallback result, ClientMessages i18n) {
SC.ask(i18n.SaveAction_Ask_Msg(), new BooleanCallback() {
@Override
public void execute(Boolean value) {
result.execute(value);
}
});
}
private static void askIgnoreValidation(final BooleanCallback result, ClientMessages i18n) {
SC.ask(i18n.SaveAction_IgnoreInvalid_Msg(), new BooleanCallback() {
@Override
public void execute(Boolean value) {
result.execute(value);
}
});
}
private static BooleanCallback getRunIfValid(
final Savable savable, final BooleanCallback saveCallback,
final boolean ask, final BooleanCallback saveIfYes,
final SaveValidation strategy, final ClientMessages i18n) {
final BooleanCallback runOnValid = new BooleanCallback() {
@Override
public void execute(Boolean valid) {
if (valid != null && valid) {
if (ask) {
askSave(saveIfYes, i18n);
} else {
savable.save(saveCallback);
}
} else if (strategy == SaveValidation.ASK) {
askIgnoreValidation(saveIfYes, i18n);
} else {
saveCallback.execute(Boolean.FALSE);
}
}
};
return runOnValid;
}
private static class SaveIfYes implements BooleanCallback {
private final Savable savable;
private final BooleanCallback saveCallback;
public SaveIfYes(Savable savable, BooleanCallback saveCallback) {
this.savable = savable;
this.saveCallback = saveCallback;
}
@Override
public void execute(Boolean confirmed) {
if (confirmed != null && confirmed) {
savable.save(saveCallback);
} else {
saveCallback.execute(Boolean.FALSE);
}
}
}
/**
* The interface should be implemented by objects able to validate
* and save its contents.
*/
public interface Savable {
void save(BooleanCallback result);
void validate(BooleanCallback result);
}
public enum SaveValidation {
/** Ask user to ignore validation result. */
ASK,
/** Ignore validation result. */
IGNORE,
/** Run validation and save only on success. */
RUN,
}
}