org.snapscript.core.ContextModule Maven / Gradle / Ivy
package org.snapscript.core;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.snapscript.common.Cache;
import org.snapscript.common.CopyOnWriteCache;
import org.snapscript.core.annotation.Annotation;
import org.snapscript.core.function.Function;
import org.snapscript.core.link.ImportManager;
public class ContextModule implements Module {
private final Cache modules;
private final Cache types;
private final List annotations;
private final List functions;
private final List references;
private final ImportManager manager;
private final Context context;
private final String prefix;
private final Scope scope;
private final Path path;
private final int order;
public ContextModule(Context context, Path path, String prefix) {
this(context, path, prefix, 0);
}
public ContextModule(Context context, Path path, String prefix, int order) {
this.manager = new ImportManager(this, path, prefix);
this.annotations = new CopyOnWriteArrayList();
this.functions = new CopyOnWriteArrayList();
this.references = new CopyOnWriteArrayList();
this.modules = new CopyOnWriteCache();
this.types = new CopyOnWriteCache();
this.scope = new ModuleScope(this);
this.context = context;
this.prefix = prefix;
this.order = order;
this.path = path;
}
@Override
public Context getContext() {
return context;
}
@Override
public ImportManager getManager() {
return manager;
}
@Override
public List getAnnotations() {
return annotations;
}
@Override
public List getFunctions() {
return functions;
}
@Override
public List getTypes() {
return references;
}
@Override
public Type addType(String name) {
Type type = types.fetch(name);
if(type != null) {
throw new ModuleException("Type '" + prefix + "." + name + "' already defined");
}
try {
TypeLoader loader = context.getLoader();
if(loader != null) {
type = loader.defineType(prefix, name);
}
if(type != null) {
types.cache(name, type);
references.add(type);
}
return type;
} catch(Exception e){
throw new ModuleException("Could not define '" + prefix + "." + name + "'", e);
}
}
@Override
public Module getModule(String name) {
try {
Module module = modules.fetch(name);
if(module == null) {
if(!types.contains(name)) { // don't resolve if its a type
module = manager.getModule(name); // import tetris.game.*
if(module != null) {
modules.cache(name, module);
}
}
}
return module;
} catch(Exception e){
throw new ModuleException("Could not find '" + name + "' in '" + prefix + "'", e);
}
}
@Override
public Type getType(String name) {
try {
Type type = types.fetch(name);
if(type == null) {
if(!modules.contains(name)) {// don't resolve if its a module
type = manager.getType(name);
if(type != null) {
types.cache(name, type);
references.add(type);
}
}
}
return type;
} catch(Exception e){
throw new ModuleException("Could not find '" + name + "' in '" + prefix + "'", e);
}
}
@Override
public Type getType(Class type) {
try {
TypeLoader loader = context.getLoader();
if(loader != null) {
return loader.loadType(type);
}
return null;
} catch(Exception e){
throw new ModuleException("Could not load " + type, e);
}
}
@Override
public InputStream getResource(String path) {
try {
ResourceManager manager = context.getManager();
if(manager != null) {
return manager.getInputStream(path);
}
return null;
} catch(Exception e){
throw new ModuleException("Could not load file '" + path + "'", e);
}
}
@Override
public Scope getScope() {
return scope;
}
@Override
public String getName() {
return prefix;
}
@Override
public Path getPath() {
return path;
}
@Override
public int getOrder() {
return order;
}
@Override
public String toString() {
return prefix;
}
}