/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.e4.ui.jobs;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.di.UISynchronize;
import org.whole.lang.bindings.BindingManagerFactory;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.bindings.ITransactionScope;
import org.whole.lang.commons.factories.CommonsEntityAdapterFactory;
import org.whole.lang.commons.reflect.CommonsEntityDescriptorEnum;
import org.whole.lang.e4.ui.actions.IE4UIConstants;
import org.whole.lang.environment.factories.EnvironmentEntityFactory;
import org.whole.lang.environment.model.Name;
import org.whole.lang.environment.reflect.EnvironmentEntityDescriptorEnum;
import org.whole.lang.factories.GenericEntityFactory;
import org.whole.lang.iterators.ConstantIterator;
import org.whole.lang.iterators.IEntityIterator;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.misc.factories.MiscEntityFactory;
import org.whole.lang.model.IEntity;
import org.whole.lang.operations.IOperationProgressMonitor;
import org.whole.lang.operations.OperationCanceledException;
import org.whole.lang.ui.viewers.IEntityPartViewer;
import org.whole.lang.util.BehaviorUtils;
import org.whole.lang.util.BindingUtils;
import org.whole.lang.util.EntityUtils;
import org.whole.lang.visitors.IVisitor;
import org.whole.lang.visitors.MissingVariableException;
/**
* @author Enrico Persiani
*/
public class ExecuteSampleModelRunnable extends AbstractRunnableWithProgress {
protected IEntity contextModel;
protected IEntity selfModel;
protected IEntity behaviorModel;
protected IBindingManager selfBindings;
public ExecuteSampleModelRunnable(IEclipseContext context, String label,
IEntity contextModel, IBindingManager selfBindings, IEntity selfModel,
IBindingManager behaviorBindings, IEntity behaviorModel) {
super(context, behaviorBindings, label);
this.contextModel = contextModel;
this.selfBindings = selfBindings;
this.selfModel = selfModel;
this.behaviorModel = behaviorModel;
}
@Override
protected boolean isTransactional() {
return false;
}
@Override
public void run(IOperationProgressMonitor pm) throws InvocationTargetException, InterruptedException {
IEntity selfEntity = EntityUtils.mapEntity(selfModel, EntityUtils.clone(EntityUtils.getCompoundRoot(selfModel)));
Set<String> initialNames = bm.wNames();
pm.beginTask("Executing sample...", IOperationProgressMonitor.TOTAL_WORK);
behaviorModel = BehaviorUtils.apply(
"whole:org.whole.lang.ui.views:SamplePerspectiveSemantics#SampleViewBehavior",
behaviorModel, bm);
IEntity derivedModel = null;
try {
IEntityIterator<?> iterator = BehaviorUtils.lazyEvaluate(behaviorModel, 0, bm);
iterator.setBindings(selfBindings);
iterator.reset(selfEntity);
if (iterator.getClass().equals(ConstantIterator.class)) {
IEntity result = iterator.next();
if (result == null || !EntityUtils.isData(result))
derivedModel = result;
else {
Object resultValue = result.wGetValue();
derivedModel = IVisitor.class.isInstance(resultValue) ?
BindingManagerFactory.instance.createValue(Matcher.match((IVisitor) resultValue, selfEntity)) : result;
}
} else if (iterator.hasNext()) {
derivedModel = MiscEntityFactory.instance.createMisc(0);
ITransactionScope transactionScope = BindingManagerFactory.instance.createTransactionScope();
bm.wEnterScope(transactionScope);
try {
for (IEntity result : iterator) {
transactionScope.commit();
derivedModel.wAdd(GenericEntityFactory.instance.create(
CommonsEntityDescriptorEnum.SameStageFragment,
//CommonsEntityFactory.instance.createSameStageFragment(
EntityUtils.clone(result)));//TODO substitute with a no containment fragment
}
} finally {
transactionScope.rollback();
bm.wExitScope();
}
}
} catch (MissingVariableException e) {
addMissingVariables(contextModel, e);
} catch (OperationCanceledException e) {
// gracefully terminate execution
} catch (Exception e) {
if (e.getCause() instanceof MissingVariableException)
addMissingVariables(contextModel, (MissingVariableException) e.getCause());
} finally {
pm.endTask();
}
IEntity variablesModel = null;
if (derivedModel != null) {
EnvironmentEntityFactory ef = EnvironmentEntityFactory.instance;
variablesModel = ef.createBindings(0);
for (String name : new TreeSet<String>(bm.wLocalNames()))
if (!initialNames.contains(name))
variablesModel.wAdd(ef.createBinding(ef.createName(name), ef.createValue(BindingUtils.wGet(bm, name))));
final IEntity contents = derivedModel;
final IEntity variables = variablesModel;
context.get(UISynchronize.class).asyncExec(new Runnable() {
public void run() {
context.get(IEntityPartViewer.class).setContents(null, contents);
context.get(IEventBroker.class).post(IE4UIConstants.TOPIC_UPDATE_VARIABLES, variables);
}
});
}
}
protected void addMissingVariables(IEntity contextModel, MissingVariableException e) {
String[] varNames = e.getVariableNames();
EnvironmentEntityFactory ef = EnvironmentEntityFactory.instance;
for (String varName : varNames) {
Name var = ef.createName(varName);
IEntity find = Matcher.find(var, contextModel, false);
if (find == null)
contextModel.wAdd(ef.createBinding(var, CommonsEntityAdapterFactory.createResolver(EnvironmentEntityDescriptorEnum.Value)));
}
}
}