/*
* 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.gui.api.model;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.util.exception.SchemaException;
import org.apache.wicket.model.IModel;
/**
* Lazy loading Wicket model. This is an IModel implementation
* that loads the model content only when needed. This is supposed
* to be used for objects that are expensive to load. So we can avoid
* loading the at all when a component that uses them is not visible.
*
* @author lazyman
*/
public abstract class LoadableModel<T> implements IModel<T> {
private T object;
private boolean loaded = false;
private boolean alwaysReload;
public LoadableModel() {
this(null, true);
}
public LoadableModel(boolean alwaysReload) {
this(null, alwaysReload);
}
public LoadableModel(T object) {
this(object, true);
}
public LoadableModel(T object, boolean alwaysReload) {
this.object = object;
this.alwaysReload = alwaysReload;
}
public T getObject() {
if (!loaded) {
setObject(load());
onLoad();
this.loaded = true;
}
if (object instanceof IModel) {
IModel model = (IModel) object;
return (T) model.getObject();
}
return object;
}
public void setObject(T object) {
if (this.object instanceof IModel) {
((IModel<T>) this.object).setObject(object);
} else {
this.object = object;
}
this.loaded = true;
}
public boolean isLoaded() {
return loaded;
}
public void reset() {
loaded = false;
}
public void detach() {
if (loaded && alwaysReload) {
this.loaded = false;
onDetach();
}
}
public IModel getNestedModel() {
if (object instanceof IModel) {
return (IModel) object;
} else {
return null;
}
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(":attached=").append(loaded).append(":object=[").append(this.object).append("]");
return builder.toString();
}
protected abstract T load();
protected void onLoad() {
}
protected void onDetach() {
}
public void revive(PrismContext prismContext) throws SchemaException {
if (isLoaded()) {
WebComponentUtil.reviveObject(object, prismContext);
}
}
}