package ch.fusun.baron.data;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import ch.fusun.baron.core.injection.ReInjector;
import ch.fusun.baron.core.rmi.KryoUtil;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.ObjectBuffer;
/**
* Default implementation of the data registry
*/
public class DataRegistryImpl implements DataRegistry, DataListener {
private static final String DATA_ID = "ch.fusun.baron.data"; //$NON-NLS-1$
private static final String DATA = "dataProvider"; //$NON-NLS-1$
private static final String CLASS = "class"; //$NON-NLS-1$
private static final String DATAUPDATE_ID = "ch.fusun.baron.dataupdate"; //$NON-NLS-1$
private final Map<Class<?>, DataProvider> data;
private final List<DataUpdate> changedData = new ArrayList<DataUpdate>();
private final List<Class<?>> updateClasses = new ArrayList<Class<?>>();
/**
* Constructor
*/
public DataRegistryImpl() {
data = new HashMap<Class<?>, DataProvider>();
IConfigurationElement[] config = Platform.getExtensionRegistry()
.getConfigurationElementsFor(DATA_ID);
try {
for (IConfigurationElement e : config) {
DataProvider bean = (DataProvider) e
.createExecutableExtension(DATA);
bean = ReInjector.getInstance().getInstanceForClass(
bean.getClass());
bean.addDataListener(this);
data.put(bean.getClass(), bean);
}
} catch (CoreException ex) {
System.err.println("Handle this error with log or so: " //$NON-NLS-1$
+ ex.getMessage());
}
config = Platform.getExtensionRegistry().getConfigurationElementsFor(
DATAUPDATE_ID);
for (IConfigurationElement e : config) {
try {
DataUpdate bean = (DataUpdate) e
.createExecutableExtension(CLASS);
updateClasses.add(bean.getClass());
} catch (CoreException ex) {
System.err.println("Handle this error with log or so: " //$NON-NLS-1$
+ ex.getMessage());
}
}
}
@Override
public List<Class<?>> getUpdateClasses() {
return updateClasses;
}
@Override
public List<DataUpdate> getFullUpdate() {
List<DataUpdate> updates = new ArrayList<DataUpdate>();
for (Class<?> clazz : data.keySet()) {
if (clazz != null) {
DataProvider dataProvider = data.get(clazz);
if (dataProvider == null) {
System.err
.println("DataProvider for " + clazz + " not found!"); //$NON-NLS-1$//$NON-NLS-2$
} else {
updates.add(dataProvider.createFullUpdate());
}
}
}
return updates;
}
@Override
public List<DataUpdate> getUpdates() {
return changedData;
}
@Override
public Collection<DataProvider> getDataProviders() {
return data.values();
}
@Override
public void persist(String path) {
Kryo kryo = new Kryo();
ObjectBuffer buffer = new ObjectBuffer(kryo, 100000);
List<DataProvider> providers = registerClasses(kryo);
try {
FileOutputStream fileOutputStream = new FileOutputStream(path);
buffer.writeObject(fileOutputStream, providers);
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private List<DataProvider> registerClasses(Kryo kryo) {
List<DataProvider> providers = new ArrayList<DataProvider>(
this.data.values());
List<Class<?>> clazzes = new ArrayList<Class<?>>();
for (DataProvider provider : providers) {
clazzes.add(provider.getClass());
}
for (Class<?> clazz : KryoUtil.getInstance()
.retrieveAllClasses(clazzes)) {
kryo.register(clazz);
}
return providers;
}
@SuppressWarnings("unchecked")
@Override
public void load(String path) {
Kryo kryo = new Kryo();
List<DataProvider> providers = registerClasses(kryo);
List<DataListener> listeners = new ArrayList<DataListener>();
for (DataProvider provider : providers) {
listeners.addAll(provider.getListeners());
provider.removeAllListeners();
}
ObjectBuffer buffer = new ObjectBuffer(kryo, 100000);
List<DataProvider> loadedProviders = null;
try {
FileInputStream fileInputStream = new FileInputStream(path);
loadedProviders = buffer.readObject(fileInputStream,
ArrayList.class);
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (loadedProviders != null) {
this.data.clear();
this.changedData.clear();
for (DataProvider dataProvider : loadedProviders) {
dataProvider.addDataListener(this);
data.put(dataProvider.getClass(), dataProvider);
ReInjector.getInstance().updateInstance(
dataProvider.getClass(), dataProvider);
}
for (DataListener listener : listeners) {
ReInjector.getInstance().reInject(listener);
listener.dataChanged(null);
}
}
}
@Override
public void dataChanged(DataUpdate update) {
changedData.add(update);
}
@Override
public void clearUpdates() {
changedData.clear();
}
}