package org.simantics.modeling.subscription; import java.util.List; import java.util.concurrent.RejectedExecutionException; import java.util.logging.Level; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.simantics.ObjectIdentitySchedulingRule; import org.simantics.db.common.procedure.adapter.ListenerAdapter; import org.simantics.db.exception.DatabaseException; import org.simantics.history.HistoryException; import org.simantics.history.util.subscription.SubscriptionItem; import org.simantics.modeling.subscription.ModelHistoryCollector.ItemCollector; /** * Listener for {@link SubscriptionCollectionResult} request. Reloads * {@link ItemCollector} on every execution. */ class VariableSetListener extends ListenerAdapter { /** * */ private final ModelHistoryCollector modelHistoryCollector; /** * @param modelHistoryCollector */ VariableSetListener(ModelHistoryCollector modelHistoryCollector) { this.modelHistoryCollector = modelHistoryCollector; } boolean disposed; @Override public void execute(final SubscriptionCollectionResult result) { Job job = new Job("Reloading history subscriptions") { @Override protected IStatus run(IProgressMonitor monitor) { try { if (VariableSetListener.this.modelHistoryCollector.itemCollector.isDisposed()) return Status.OK_STATUS; if (!result.getStatus().isOK() && VariableSetListener.this.modelHistoryCollector.logger != null) VariableSetListener.this.modelHistoryCollector.logger.log(result.getStatus()); // Load in specified thread. final IStatus[] status = { null }; Runnable loader = new Runnable() { @Override public void run() { try { List sampledItems = ModelHistoryCollector.sampledSubscriptionItems(result.getSubscriptions()); VariableSetListener.this.modelHistoryCollector.itemCollector.load( sampledItems ); } catch (HistoryException e) { status[0] = new Status(IStatus.ERROR, "org.simantics.modeling", e.getLocalizedMessage(), e); if (VariableSetListener.this.modelHistoryCollector.logger != null) VariableSetListener.this.modelHistoryCollector.logger.log(status[0]); } catch (DatabaseException e) { VariableSetListener.this.modelHistoryCollector.log.log(Level.WARNING, "Unexpected failure in history variable collection request.", e); status[0] = new Status(IStatus.ERROR, "org.simantics.modeling", e.getLocalizedMessage(), e); } } }; if (VariableSetListener.this.modelHistoryCollector.loadThread != null) VariableSetListener.this.modelHistoryCollector.loadThread.syncExec(loader); else loader.run(); if (status[0] == null && VariableSetListener.this.modelHistoryCollector.loadCallback != null) VariableSetListener.this.modelHistoryCollector.loadCallback.run(); return status[0] != null ? status[0] : Status.OK_STATUS; } catch (RejectedExecutionException e) { // IThreadWorkQueue.syncExec may produce this. // Usually this means the executor has been // disposed. return new Status(IStatus.INFO, "org.simantics.modeling", e.getLocalizedMessage(), e); } finally { VariableSetListener.this.modelHistoryCollector.initMutex.release(); } } }; job.setRule(new ObjectIdentitySchedulingRule(this.modelHistoryCollector)); job.setUser(false); job.schedule(); } public void dispose() { disposed = true; } @Override public void exception(Throwable t) { this.modelHistoryCollector.initMutex.release(); this.modelHistoryCollector.log.log(Level.WARNING, "Unexpected failure in history variable collection request.", t); } @Override public boolean isDisposed() { return disposed; } }