/*
* This file is part of ReadonlyREST.
*
* ReadonlyREST 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.
*
* ReadonlyREST 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 ReadonlyREST. If not, see http://www.gnu.org/licenses/
*/
package org.elasticsearch.plugin.readonlyrest.requestcontext;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.plugin.readonlyrest.ESContext;
import java.util.Objects;
/**
* The representation of a Transient object that has:
* - an immutable initial req,
* - a mutable tranient req
* - an immutable final req
* - a custom function that is executed when the final req is being frozen.
* <p>
* NB: If a Delayed.reset() is executed, the tranisent req returns to the initial req.
* <p>
* Created by sscarduzio on 14/04/2017.
*/
public abstract class Transactional<T> extends Delayed {
private final Logger logger;
private Boolean initialized = false;
private T initialValue;
private T transientValue;
public Transactional(String name, ESContext context) {
super(name, context);
this.logger = context.logger(getClass());
}
@Override
public void commit() {
delay( () -> {
if (!initialized) {
lazyLoad();
}
if (transientValue == null && initialValue == null || Objects.equals(transientValue, initialValue)) {
logger.debug(name + " > nothing to be committed..");
return;
}
logger.debug(name + " > committing final req " + transientValue);
onCommit(transientValue);
});
super.commit();
}
private void lazyLoad() {
initialized = true;
initialValue = initialize();
transientValue = copy(this.initialValue);
logger.debug(name + " > lazy loading initial req to " + initialValue);
}
public abstract T initialize();
public abstract T copy(T initial);
public abstract void onCommit(T value);
public T get() {
if (!initialized) {
lazyLoad();
}
return transientValue;
}
public T getInitial() {
if (!initialized) {
lazyLoad();
}
return initialValue;
}
public void mutate(T newValue) {
if (!initialized) {
lazyLoad();
}
this.transientValue = newValue;
}
@Override
public void reset() {
if (initialized) {
transientValue = initialValue;
}
super.reset();
}
}