Package org.rascalmpl.tasks

Source Code of org.rascalmpl.tasks.PDBValueTaskRegistry

/*******************************************************************************
* 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.tasks;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.imp.pdb.facts.IValue;
import org.eclipse.imp.pdb.facts.type.Type;
import org.rascalmpl.interpreter.IRascalMonitor;
import org.rascalmpl.interpreter.asserts.ImplementationError;

public class PDBValueTaskRegistry extends TaskRegistry<Type, IValue, IValue> implements ITaskRegistry<Type, IValue, IValue> {
  private static volatile PDBValueTaskRegistry instance = null;
  private Map<Type,Map<Type,ITask<Type,IValue,IValue>>> keyedProducers = new HashMap<Type,Map<Type,ITask<Type,IValue,IValue>>>();

  public static PDBValueTaskRegistry getRegistry() {
    if(instance == null) {
      synchronized(PDBValueTaskRegistry.class) {
        if(instance == null)
          instance = new PDBValueTaskRegistry();
      }
    }
    return instance;
  }

  private PDBValueTaskRegistry() {
    super();
  }
  /* (non-Javadoc)
   * @see org.rascalmpl.tasks.ITaskRegistry#getProducer(Type, IValue)
   */
  @Override
  public ITask<Type,IValue,IValue> getProducer(Type key, IValue name) {
    lock.lock();
    try {
      Map<Type, ITask<Type, IValue, IValue>> producerMap = keyedProducers.get(key);
      if(producerMap != null) {
        Type nameType = name.getType();
        if(producerMap.containsKey(nameType))
          return producerMap.get(nameType);
        for(Map.Entry<Type, ITask<Type, IValue, IValue>> t : producerMap.entrySet()) {
          if(nameType.isSubtypeOf(t.getKey()))
            return t.getValue();
        }
      }
      throw new ImplementationError("No suitable producer found for " + key + "(" + name + ")");
    }
    finally {
      lock.unlock();
    }
  }

  /* (non-Javadoc)
   * @see org.rascalmpl.tasks.ITaskRegistry#produce(org.rascalmpl.interpreter.IRascalMonitor, org.rascalmpl.tasks.ITransaction, Type, IValue)
   */
  @Override
  public boolean produce(IRascalMonitor monitor, ITransaction<Type, IValue, IValue> tr, Type key, IValue name) {
    ITask<Type, IValue, IValue> producer = null;
    lock.lock();
    try {
      producer = getProducer(key, name);
    }
    finally {
      lock.unlock();
    }
    if(producer == null)
      throw new ImplementationError("No registered fact producer for " + key.toString());
    return producer.produce(monitor, tr, key, name);
  }

  /* (non-Javadoc)
   * @see org.rascalmpl.tasks.ITaskRegistry#registerProducer(org.rascalmpl.tasks.ITask)
   */
  @Override
  public void registerProducer(ITask<Type,IValue,IValue> producer) {
    lock.lock();
    try {
      for(Type key : producer.getKeys()) {
        if(key.isTuple()) {
          Type key1 = key.getFieldType(0);
          Type key2 = key.getFieldType(1);
          Map<Type, ITask<Type, IValue, IValue>> map = keyedProducers.get(key1);
          if(map == null)
            map = new HashMap<Type, ITask<Type, IValue, IValue>>();
          map.put(key2, producer);
          keyedProducers.put(key1, map);
        }
        else {
          producers.put(key, producer);
        }
      }
    }
    finally {
      lock.unlock();
    }
  }

  /* (non-Javadoc)
   * @see org.rascalmpl.tasks.ITaskRegistry#unregisterProducer(org.rascalmpl.tasks.ITask)
   */
  @Override
  public void unregisterProducer(ITask<Type,IValue,IValue> producer) {
    lock.lock();
    try {
      for(Type key : producer.getKeys()) {
        if(key.isTuple()) {
          Type key1 = key.getFieldType(0);
          Map<Type, ITask<Type, IValue, IValue>> map = keyedProducers.get(key1);
          if(map != null) {
            for(Map.Entry<Type, ITask<Type,IValue,IValue>> entry : map.entrySet()) {
              if(entry.getValue().equals(producer))
                map.remove(entry.getKey());
            }
            if(map.isEmpty())
              keyedProducers.remove(key1);
            else
              keyedProducers.put(key1, map);
          }
        }
        else {
          if(producers.get(key) == producer)
            producers.remove(key);
        }
      }
    }
    finally {
      lock.unlock();
    }
  }


  /* (non-Javadoc)
   * @see org.rascalmpl.tasks.ITaskRegistry#getKeys()
   */
  @Override
  public Collection<Type> getKeys() {
    lock.lock();
    try {
      Set<Type> set = new HashSet<Type>();
      set.addAll(keyedProducers.keySet());
      set.addAll(super.getKeys());
      return set;
    }
    finally {
      lock.unlock();
    }
  }

  /* (non-Javadoc)
   * @see org.rascalmpl.tasks.ITaskRegistry#clear()
   */
  @Override
  public void clear() {
    lock.lock();
    try {
      keyedProducers.clear();
      super.clear();
    }
    finally {
      lock.unlock();
    }
  }

}
TOP

Related Classes of org.rascalmpl.tasks.PDBValueTaskRegistry

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.