/*
* Copyright (c) 2010-2016 Evolveum
*
* 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 com.evolveum.midpoint.web.component.refresh;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.util.time.Duration;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* EXPERIMENTAL. (Working with these timers is very tricky. What we really need is flexible re-scheduling of these timers.)
*
* @author mederly
*/
public abstract class RemovableAjaxTimerBehavior extends AbstractAjaxTimerBehavior {
private static final Trace LOGGER = TraceManager.getTrace(RemovableAjaxTimerBehavior.class);
@NotNull private final Component parent;
private final long updateInterval;
private boolean enabled = true;
private long expires;
public RemovableAjaxTimerBehavior(@NotNull Component parent, long updateInterval) {
super(Duration.milliseconds(updateInterval));
this.updateInterval = updateInterval;
this.parent = parent;
}
@Override
protected void onTimer(AjaxRequestTarget target) {
LOGGER.trace("onTimer called for {}; enabled = {}", this, enabled);
if (enabled) {
handleOnTimer(target);
}
cleanup();
}
public void cleanup() {
synchronized (parent) {
List<RemovableAjaxTimerBehavior> toBeRemoved = new ArrayList<>();
for (Behavior behavior : parent.getBehaviors()) {
if (behavior instanceof RemovableAjaxTimerBehavior && ((RemovableAjaxTimerBehavior) behavior).isExpired()) {
toBeRemoved.add((RemovableAjaxTimerBehavior) behavior);
}
}
for (RemovableAjaxTimerBehavior behavior : toBeRemoved) {
LOGGER.trace("Removing {} from {}", behavior, parent);
parent.remove(behavior);
}
}
}
private boolean isExpired() {
return expires != 0 && System.currentTimeMillis() >= expires;
}
protected abstract void handleOnTimer(AjaxRequestTarget target);
public void remove(AjaxRequestTarget target) {
LOGGER.trace("remove() called, setting enabled := false and calling stop() method [{}]", this);
enabled = false;
expires = System.currentTimeMillis() + 2*updateInterval;
stop(target);
cleanup(); // just to call cleanup at every possible place
}
}