Package org.rascalmpl.library.util.tasks

Source Code of org.rascalmpl.library.util.tasks.Manager$ProducerWrapper

/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* 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
*
* Contributors:

*   * Anya Helene Bagge - anya@ii.uib.no (Univ. Bergen)
*******************************************************************************/
package org.rascalmpl.library.util.tasks;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.imp.pdb.facts.IBool;
import org.eclipse.imp.pdb.facts.IConstructor;
import org.eclipse.imp.pdb.facts.ISet;
import org.eclipse.imp.pdb.facts.ITuple;
import org.eclipse.imp.pdb.facts.IValue;
import org.eclipse.imp.pdb.facts.IValueFactory;
import org.eclipse.imp.pdb.facts.type.Type;
import org.eclipse.imp.pdb.facts.type.TypeFactory;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.IRascalMonitor;
import org.rascalmpl.interpreter.TypeReifier;
import org.rascalmpl.interpreter.asserts.ImplementationError;
import org.rascalmpl.interpreter.result.ICallableValue;
import org.rascalmpl.interpreter.result.Result;
import org.rascalmpl.interpreter.staticErrors.UnexpectedType;
import org.rascalmpl.interpreter.utils.RuntimeExceptionFactory;
import org.rascalmpl.tasks.IIValueTask;
import org.rascalmpl.tasks.ITaskRegistry;
import org.rascalmpl.tasks.ITransaction;
import org.rascalmpl.tasks.PDBValueTaskRegistry;
import org.rascalmpl.tasks.Transaction;
import org.rascalmpl.values.ValueFactoryFactory;

public class Manager {
  private Transaction base = null;
  private final ITaskRegistry<Type, IValue, IValue> registry;
  private final IValueFactory vf;
  private final TypeReifier typeReifier;
  private final Map<IValueWrapper,ProducerWrapper> producers = new HashMap<IValueWrapper,ProducerWrapper>();
 
  public Manager() {
    this(ValueFactoryFactory.getValueFactory());
  }
 
  public Manager(IValueFactory vf) {
    this.vf = vf;
    this.typeReifier = new TypeReifier(vf);
    this.registry = PDBValueTaskRegistry.getRegistry();
  }
 
  public void lockProducerRegistry() {
    registry.lock();
  }
 
  public void unlockProducerRegistry() {
    registry.unlock();
  }
 
  public IValue startTransaction(IEvaluatorContext ctx) {
    if(base == null)
      base = new Transaction(ctx.getStdErr());
    return new Transaction(base, ctx.getStdErr());
  }
 
  public IValue startTransaction(IValue tr, IEvaluatorContext ctx) {
    return new Transaction(transaction(tr), ctx.getStdErr());
  }
 
  public void endTransaction(IValue tr) {
    transaction(tr).commit();
  }

  public void abandonTransaction(IValue tr) {
    transaction(tr).abandon();
  }
 
  public IValue getFact(IValue tr, IValue key, IValue name, IEvaluatorContext ctx) {
    if(!(key instanceof IConstructor))
      throw RuntimeExceptionFactory.illegalArgument(key, ctx.getCurrentAST(), ctx.getStackTrace(), "key is not a reified type");

    IValue fact = transaction(tr).getFact(ctx, typeReifier.valueToType((IConstructor) key), name);
    if(fact == null)
      fact = null; // <- put breakpoint here!
    return check(fact, (IConstructor) key, name, ctx);
  }

  private IValue check(IValue fact, IValue key, IValue name, IEvaluatorContext ctx) {
    if(!(key instanceof IConstructor))
      throw RuntimeExceptionFactory.illegalArgument(key, ctx.getCurrentAST(), ctx.getStackTrace(), "key is not a reified type");

    if(fact == null)
      throw RuntimeExceptionFactory.noSuchKey(vf.string(typeReifier.valueToType((IConstructor) key).toString() + ":" + name.toString()),
          ctx.getCurrentAST(), ctx.getStackTrace());
    else if(!fact.getType().isSubtypeOf(typeReifier.valueToType((IConstructor) key)))
      throw new UnexpectedType(typeReifier.valueToType((IConstructor) key), fact.getType(), ctx.getCurrentAST());
    else
      return fact;
  }

  public IValue queryFact(IValue tr, IValue key, IValue name, IEvaluatorContext ctx) {
    if(!(key instanceof IConstructor))
      throw RuntimeExceptionFactory.illegalArgument(key, ctx.getCurrentAST(), ctx.getStackTrace(), "key is not a reified type");

    return check(transaction(tr).queryFact(typeReifier.valueToType((IConstructor) key), name), key, name, ctx);
  }

  public void removeFact(IValue tr, IValue key, IValue name, IEvaluatorContext ctx) {
    if(!(key instanceof IConstructor))
      throw RuntimeExceptionFactory.illegalArgument(key, ctx.getCurrentAST(), ctx.getStackTrace(), "key is not a reified type");

    transaction(tr).removeFact(typeReifier.valueToType((IConstructor) key), name);
  }

  public void setFact(IValue tr, IValue key, IValue name, IValue value, IEvaluatorContext ctx) {
    if(!(key instanceof IConstructor))
      throw RuntimeExceptionFactory.illegalArgument(key, ctx.getCurrentAST(), ctx.getStackTrace(), "key is not a reified type");

    Type keyType = typeReifier.valueToType((IConstructor) key);
    if(!value.getType().isSubtypeOf(keyType))
      throw new UnexpectedType(keyType, value.getType(), ctx.getCurrentAST());
    else
      transaction(tr).setFact(keyType, name, value);
  }
 
  public void registerProducer(IValue producer, ISet keys, IEvaluatorContext ctx) {
    ProducerWrapper wrapper = new ProducerWrapper(ctx, (ICallableValue)producer, keys);
    producers.put(new IValueWrapper(producer), wrapper);
    registry.registerProducer(wrapper);
  }
 

  public void unregisterProducer(IValue producer) {
    IValueWrapper prod = new IValueWrapper(producer);
    if(producers.containsKey(prod)) {
      ProducerWrapper wrapper = producers.get(prod);
      registry.unregisterProducer(wrapper);
      producers.remove(prod);
    }
  }
 
  public ITuple getDependencyGraph(IValue tr) {
    return transaction(tr).getGraph();
  }

  protected IConstructor reify(IEvaluatorContext ctx, Type type) {
    return (IConstructor) typeReifier.typeToValue(type, ctx).getValue();
  }
  /**
   *  Cast an IValue to ITransaction
   */
  protected static Transaction transaction(IValue tr) {
    if(tr instanceof Transaction)
      return (Transaction)tr;
    else
      throw new ImplementationError("Not a transaction: " + tr);
  }
 
  class ProducerWrapper implements IIValueTask {
   
    private ICallableValue fun;
    private IEvaluatorContext ctx;
    private Collection<Type> keys = new ArrayList<Type>();
   
    ProducerWrapper(IEvaluatorContext ctx, ICallableValue fun, ISet keys) {
      this.ctx = ctx;
      this.fun = fun;
      for(IValue v : keys) {
        if(v instanceof ITuple) {
          IValue keyType = ((ITuple)v).get(0);
          IValue nameType = ((ITuple)v).get(1);
          this.keys.add(TypeFactory.getInstance().tupleType(
              typeReifier.valueToType((IConstructor)keyType),
              typeReifier.valueToType((IConstructor)nameType)));
        }
        else {
          this.keys.add(TypeFactory.getInstance().tupleType(
              typeReifier.valueToType((IConstructor)v),
              TypeFactory.getInstance().valueType()));
        }
      }
    }
   
    public boolean produce(IRascalMonitor monitor, ITransaction<Type, IValue, IValue> tr,
        Type key, IValue name) {
      Transaction t = (Transaction)tr;
      IValue reifiedKey = reify(ctx, key);
      Result<IValue> result = fun.call(monitor, new Type[] {t.getType(), reifiedKey.getType(), name.getType()},
          new IValue[] {t, reifiedKey, name}, null);
      if(result.getValue() instanceof IBool)
        return ((IBool)result.getValue()).getValue();
      else
        throw new UnexpectedType(TypeFactory.getInstance().boolType(), result.getType(), ctx.getCurrentAST());
       
    }
   
    public Collection<Type> getKeys() {
      return keys;
    }
   
  }


}
class IValueWrapper {
  private final IValue value;
 
  IValueWrapper(IValue value) {
    this.value = value;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((value == null) ? 0 : value.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    IValueWrapper other = (IValueWrapper) obj;
    if (value == null) {
      if (other.value != null)
        return false;
    } else if (!value.isEqual(other.value))
      return false;
    return true;
  }

}
TOP

Related Classes of org.rascalmpl.library.util.tasks.Manager$ProducerWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.