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;
+	}
+
+}