package abstrasy;
/**
* Abstrasy Interpreter
*
* Copyright : Copyright (c) 2006-2012, Luc Bruninx.
*
* Concédée sous licence EUPL, version 1.1 uniquement (la «Licence»).
*
* Vous ne pouvez utiliser la présente oeuvre que conformément à la Licence.
* Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
*
* http://www.osor.eu/eupl
*
* Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
* la Licence est distribué "en l’état", SANS GARANTIES OU CONDITIONS QUELLES
* QU’ELLES SOIENT, expresses ou implicites.
*
* Consultez la Licence pour les autorisations et les restrictions
* linguistiques spécifiques relevant de la Licence.
*
*
* @author Luc Bruninx
* @version 1.0
*/
import abstrasy.externals.AExtClonable;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.StdErrors;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class Hash implements AExtClonable {
public final static long KEY_TYPES =
Node.TYPE_NOTHING | Node.TYPE_NUMBER | Node.TYPE_PCODE | Node.TYPE_STRING | Node.TYPE_QSYMBOL | Node.TYPE_QNUMBER | Node.TYPE_QPCODE | Node.TYPE_QSTRING;
@Override
public Object clone_my_self(Bivalence bival) throws Exception {
Hash h=new Hash();
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext()){
String k=kit.next();
Item item=map.get(k);
h.map.put(k,new Item(item.getKey(),Node.createClone(item.getValue(), bival)));
}
return h;
}
public Hash copy_my_self() throws Exception {
Hash h=new Hash();
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext()){
String k=kit.next();
Item item=map.get(k);
h.map.put(k,new Item(item.getKey(),item.getValue()));
}
return h;
}
private static final class Item{
private Node key;
private Node value;
Item(Node key, Node value) throws InterpreterException {
try {
this.key=Node.createClone(key);
}
catch (Exception e) {
if(Interpreter.isDebugMode()){
e.printStackTrace();
Interpreter.Log(e.toString());
}
throw new InterpreterException(StdErrors.extend(StdErrors.Object_not_clonable, e.getMessage()));
}
this.value=value;
}
Node getKey() {
return key;
}
Node getValue() {
return value;
}
}
private HashMap<String, Item> map = new HashMap<String, Item>();
private boolean finale=false;
public Hash() {
}
private static final String _keyToString(Node k) throws InterpreterException {
k.requireNodeType(KEY_TYPES);
return k.toString().trim();
}
/**
* Permet de récupérer le Node enregistré dans la table à l'aide de la clé k.
*
* Si la clé k n'existe pas, elle est toutefois créée dynamiquement. De cette
* manière l'intégrité référentielle de la table est respectée.
*
* On peut assigner les valeurs par node.derefTo(Hash.ref(K))...
*
* @param k
* @return v (ou une nouvelle cellule Node si k n'existe pas)
* @throws InterpreterException
*/
public Node ref(Node k) throws InterpreterException {
String ks=_keyToString(k);
if(map.containsKey(ks))
return map.get(ks).getValue();
Node r=Node.createNothing();
Item item = new Item(k,r);
map.put(ks, item);
return r;
}
/**
* Place ou remplace le Node dans la table à l'aide de la clé k.
*
* @param k
* @return v (ou une nouvelle cellule Node si k n'existe pas)
* @throws InterpreterException
*/
public void store(Node k,Node v) throws InterpreterException {
String ks=_keyToString(k);
Item item = new Item(k,v);
map.put(ks, item);
}
public Node get(String ks){
return map.get(ks).getValue();
}
/**
* Retourne la liste des chaînes de caractères qui identifient les valeurs
*
* @return r (ArrayList of Strings)
*/
public ArrayList<String> keys_strings(){
ArrayList<String> r=new ArrayList<String>();
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext())
r.add(kit.next());
return r;
}
/**
* Retourne la liste des Nodes qui constitue les identifiants sources.
*
* Il s'agit d'un accès direct au Nodes, il ne s'agit pas de copie.
*
* @return r (ArrayList of Nodes)
*/
public ArrayList<Node> keys_nodes(){
ArrayList<Node> r=new ArrayList<Node>();
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext())
r.add(map.get(kit.next()).getKey());
return r;
}
/**
* Retourne la liste des Nodes qui forment l'ensemble des valeurs de la liste.
*
* Les données sont fournies dans un ordre quelconque (format brut).
*
* @return
*/
public ArrayList<Node> values_nodes(){
ArrayList<Node> r=new ArrayList<Node>();
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext())
r.add(map.get(kit.next()).getValue());
return r;
}
/**
* Indique la taille de la liste
*
* @return
*/
public int size() {
return map.size();
}
public boolean hasKey(String k){
return map.containsKey(k);
}
public boolean hasKey(Node k) throws InterpreterException {
return hasKey(_keyToString(k));
}
public boolean remove(String k){
Item item = map.remove(k);
return item!=null;
}
public boolean remove(Node k) throws InterpreterException {
return remove(_keyToString(k));
}
public boolean hasValue(Node v) throws Exception {
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext()){
Item item= map.get(kit.next());
if(Node.equalsNodes(v, item.getValue()))
return true;
}
return false;
}
public ArrayList<String> findKeys_strings(Node v) throws Exception {
ArrayList<String> r=new ArrayList<String>();
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext()){
String k=kit.next();
Item item=map.get(k);
if(Node.equalsNodes(v, item.getValue()))
r.add(k);
}
return r;
}
public ArrayList<Node> findKeys_nodes(Node v) throws Exception {
ArrayList<Node> r=new ArrayList<Node>();
Iterator<String> kit=map.keySet().iterator();
while(kit.hasNext()){
String k=kit.next();
Item item=map.get(k);
if(Node.equalsNodes(v, item.getValue()))
r.add(item.getKey());
}
return r;
}
}