/** * (C) Copyright 2013 Jabylon (http://www.jabylon.org) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.jabylon.rest.ui.model; import java.io.Serializable; import org.apache.wicket.model.IModel; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.jabylon.rest.ui.Activator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; public abstract class AbstractEMFModel<T extends CDOObject, R> implements IModel<R> { private static final long serialVersionUID = 1L; private static final Logger LOGGER = LoggerFactory.getLogger(AbstractEMFModel.class); protected Supplier<T> modelSupplier; protected long id; public AbstractEMFModel(T model) { super(); id=CDOIDUtil.getLong(model.cdoID()); this.modelSupplier = Suppliers.memoize(new LoadingSupplier<T>(model)); } protected T getDomainObject() { T t = modelSupplier.get(); if(t==null) { LOGGER.warn("Lost for some reason the model supplier. Trying to recover"); modelSupplier = Suppliers.memoize(new LoadingSupplier<T>(id)); t = modelSupplier.get(); LOGGER.warn("Recovered to "+t); } return t; } protected void setDomainObject(T domainObject) { this.modelSupplier = Suppliers.memoize(Suppliers.ofInstance(domainObject)); } @Override public void detach() { modelSupplier = Suppliers.memoize(new LoadingSupplier<T>(id)); } private static final class LookupFunction<X> implements Serializable, Function<Long, X> { /** field <code>serialVersionUID</code> */ private static final long serialVersionUID = -7243181664341900603L; @SuppressWarnings("unchecked") @Override public X apply(Long from) { CDOID id = CDOIDUtil.createLong(from); CDOObject cdoObject = Activator.getDefault().getRepositoryLookup().resolve(id); return (X)cdoObject; } } private static final class LoadingSupplier<T> implements Supplier<T>, Serializable { private static final long serialVersionUID = 1L; private transient T instance; private LookupFunction<T> function; private long id; public LoadingSupplier(T instance) { super(); this.instance = instance; function = new LookupFunction<T>(); } public LoadingSupplier(long id) { super(); this.instance = null; this.id = id; function = new LookupFunction<T>(); } @Override public T get() { if(instance==null) instance = function.apply(id); return instance; } } @SuppressWarnings("rawtypes") @Override public boolean equals(Object obj) { if (obj instanceof AbstractEMFModel) { AbstractEMFModel other = (AbstractEMFModel) obj; return other.id == id; } return false; } @Override public int hashCode() { return (int)id; } }