/* * 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; import com.evolveum.midpoint.web.resource.img.ImgResources; import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.web.component.util.FutureUpdateBehavior; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.image.Image; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.request.resource.PackageResourceReference; import org.apache.wicket.request.resource.ResourceReference; import org.apache.wicket.util.time.Duration; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import java.io.Serializable; import java.util.concurrent.Future; /** * @author lazyman */ public abstract class AsyncUpdatePanel<V, T extends Serializable> extends BasePanel<T> { private static final ResourceReference PRELOADER = new PackageResourceReference(ImgResources.class, "ajax-loader.gif"); /** * Duration in seconds. */ public static final int DEFAULT_TIMER_DURATION = 2; protected transient Future<T> future; private boolean loadingVisible = true; public AsyncUpdatePanel(String id, IModel<V> callableParameterModel) { this(id, callableParameterModel, Duration.seconds(DEFAULT_TIMER_DURATION)); } public AsyncUpdatePanel(String id, IModel<V> callableParameterModel, Duration durationSecs) { super(id, new Model<T>()); Authentication auth = SecurityContextHolder.getContext().getAuthentication(); future = GuiComponents.submitCallable(createCallable(auth, callableParameterModel)); FutureUpdateBehavior<T> behaviour = new FutureUpdateBehavior<T>(durationSecs, future) { @Override protected void onPostSuccess(AjaxRequestTarget target) { loadingVisible = false; AsyncUpdatePanel.this.onPostSuccess(target); } @Override protected void onUpdateError(AjaxRequestTarget target, Exception ex) { loadingVisible = false; AsyncUpdatePanel.this.onUpdateError(target, ex); } }; add(behaviour); } protected abstract void onPostSuccess(AjaxRequestTarget target); protected abstract void onUpdateError(AjaxRequestTarget target, Exception ex); protected boolean isLoadingVisible() { return loadingVisible; } protected Component getLoadingComponent(final String markupId) { Image image = new Image(markupId, PRELOADER); image.add(new VisibleEnableBehaviour() { @Override public boolean isVisible() { return isLoadingVisible(); } }); return image; } protected abstract Component getMainComponent(final String markupId); /** * Create a callable that encapsulates the actual fetching of the data needed * by the panel for rendering. * * @param auth provides {@link org.springframework.security.core.Authentication} object (principal) for async * thread which will be used with callable * @param callableParameterModel Model providing access to parameters needed by the callable * @return A callable instance that encapsulates the logic needed to obtain the panel data */ protected abstract SecurityContextAwareCallable<T> createCallable(Authentication auth, IModel<V> callableParameterModel); }