/*******************************************************************************
* 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
*******************************************************************************/
package org.rascalmpl.eclipse.library.vis.util;
import static org.rascalmpl.eclipse.library.vis.properties.Properties.ID;
import java.util.HashMap;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.utils.RuntimeExceptionFactory;
import org.rascalmpl.eclipse.library.vis.figure.Figure;
public class NameResolver {
private final NameResolver parent;
private final HashMap<String, Object> localFigures;
private final HashMap<String,NameResolver> children;
private final IEvaluatorContext ctx;
public NameResolver(NameResolver parent, IEvaluatorContext ctx){
this.parent = parent;
this.ctx = ctx;
localFigures = new HashMap<String, Object>();
children = new HashMap<String, NameResolver>();
}
public NameResolver(IEvaluatorContext ctx){
this(null,ctx);
}
public void register(Figure fig){
String id = fig.prop.getStr(ID);
if(id != null && !id.equals("")){
localFigures.put(id, fig);
}
}
public void register(String name, Object fig){
localFigures.put(name, fig);
}
public NameResolver newChild(String name){
NameResolver child = new NameResolver(this, ctx);
children.put(name, child);
return child;
}
public Object resolve(String path){
if(path.startsWith("../")){
if(isRoot()){
throw RuntimeExceptionFactory.figureException("Could not resolve " + path + ":no such parent", ctx.getValueFactory().string(""), ctx.getCurrentAST(),
ctx.getStackTrace());
} else {
return parent.resolve(path.substring("../".length()));
}
} else if(path.startsWith("/")){
return root().resolve(path);
} else if(path.contains("/")){
int nameSpaceEnd = path.indexOf("/");
String nameSpace = path.substring(0,nameSpaceEnd);
if(children.containsKey(nameSpace)){
return children.get(nameSpace).resolve(path.substring(nameSpaceEnd+1));
} else {
throw RuntimeExceptionFactory.figureException("Could not resolve " + path + ":no such child namespace", ctx.getValueFactory().string(""), ctx.getCurrentAST(),
ctx.getStackTrace());
}
} else {
if(localFigures.containsKey(path)){
return localFigures.get(path);
} else if(!isRoot()){
return parent.resolve(path);
} else {
return null;
}
}
}
public Figure resolveFigure(String path){
Object res = resolve(path);
if(res instanceof Figure){
return (Figure)res;
} else {
return null;
}
}
public MaxFontAscent resolveMaxFontAscent(String path){
Object res = resolve(path);
if(res instanceof MaxFontAscent){
return (MaxFontAscent)res;
} else {
return null;
}
}
public boolean isRoot() {
return parent == null;
}
public NameResolver root(){
if(isRoot()) {
return this;
} else {
return parent.root();
}
}
}