Mercurial Hosting > nabble
diff src/nabble/naml/compiler/JavaNamespace.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nabble/naml/compiler/JavaNamespace.java Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,105 @@ +package nabble.naml.compiler; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; +import fschmidt.util.java.Computable; +import fschmidt.util.java.Memoizer; + + +final class JavaNamespace implements GenericNamespace { + final Class cls; + private final boolean isGlobal; + private final boolean isTransparent; + final String name; + final Class extensionTarget; + final Constructor extensionConstructor; + private final List<String> names = new ArrayList<String>(); + + private JavaNamespace(Class<?> cls,Namespace namespace) { + this.cls = cls; + this.name = namespace.name(); + this.isGlobal = namespace.global(); + this.isTransparent = namespace.transparent(); + this.extensionTarget = null; + this.extensionConstructor = null; + addNames(cls); + } + + private JavaNamespace(Class<?> cls,NamespaceExtension namespaceExt) { + this.cls = cls; + this.name = namespaceExt.name(); + this.extensionTarget = namespaceExt.target(); + this.isGlobal = getNamespace(extensionTarget).isGlobal; + this.isTransparent = true; + try { + this.extensionConstructor = cls.getConstructor(extensionTarget); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + addNames(cls); + } + + @Override public boolean isGlobal() { + return isGlobal; + } + + @Override public boolean isTransparent() { + return isTransparent; + } + + @Override public List<String> names() { + return names; + } + + @Override public String getId() { + return cls.getName(); + } + + private void addNames(Class<?> c) { + if( c==null ) + return; + Namespace namespace = c.getAnnotation(Namespace.class); + if( namespace != null ) { + names.add( namespace.name() ); + } + NamespaceExtension namespaceExt = c.getAnnotation(NamespaceExtension.class); + if( namespaceExt != null ) + names.add(namespaceExt.name()); + addNames(c.getSuperclass()); +/* + for( Class ifc : c.getInterfaces() ) { + addNames(ifc); + } +*/ + } + + public String toString() { + return name; + } + + + private static Memoizer<Class<?>,JavaNamespace> cache = new Memoizer<Class<?>,JavaNamespace>(new Computable<Class<?>,JavaNamespace>() { + public JavaNamespace get(Class<?> cls) { + Namespace namespace = cls.getAnnotation(Namespace.class); + if( namespace != null ) + return new JavaNamespace(cls,namespace); + NamespaceExtension namespaceExt = cls.getAnnotation(NamespaceExtension.class); + if( namespaceExt != null ) + return new JavaNamespace(cls,namespaceExt); + throw new TemplateRuntimeException(""+cls+" isn't annotated as a Namespace or NamespaceExtension"); + } + }); + + static JavaNamespace getNamespace(Class cls) { + return cache.get(cls); + } + + static JavaNamespace getNamespaceExt(Class cls) { + JavaNamespace ns = getNamespace(cls); + if( ns.extensionTarget == null ) + throw new RuntimeException(""+cls+" isn't NamespaceExtension"); + return ns; + } + +}