view src/nabble/view/web/template/DocNamespace.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 source

package nabble.view.web.template;

import nabble.model.Site;
import nabble.naml.compiler.Command;
import nabble.naml.compiler.CommandSpec;
import nabble.naml.compiler.CompileException;
import nabble.naml.compiler.IPrintWriter;
import nabble.naml.compiler.Interpreter;
import nabble.naml.compiler.JavaCommand;
import nabble.naml.compiler.Meaning;
import nabble.naml.compiler.Namespace;
import nabble.naml.compiler.ScopedInterpreter;
import nabble.naml.namespaces.ListSequence;
import nabble.naml.namespaces.StringList;

import javax.servlet.ServletException;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


@Namespace (
	name = "doc",
	global = true
)
public class DocNamespace {

	static String getDocName(String macroName,Collection<String> requiredNamespaces) {
		StringBuilder buf = new StringBuilder();
		buf.append( "doc for " ).append( macroName );
		if( !requiredNamespaces.isEmpty() ) {
			Iterator<String> iter = requiredNamespaces.iterator();
			buf.append( " requiring " ).append( iter.next() );
			while( iter.hasNext() ) {
				buf.append( "," ).append( iter.next() );
			}
		}
		return buf.toString();
	}


	@Namespace (
		name = "binary_doc",
		global = true
	)
	public static final class BinaryDocNamespace extends DocNamespace {

		private final Site site;
		private final JavaCommand meaning;

		private final String value;
		private final String[] params;
		private final String[] seeAlso;

		BinaryDocNamespace(Site site, JavaCommand meaning,String value, String[] params, String[] seeAlso) {
			this.site = site;
			this.meaning = meaning;
			this.value = value;
			this.params = params;
			this.seeAlso = seeAlso;
		}

		@Command("value") public void _value(IPrintWriter out,Interpreter interp) {
			out.print(value);
		}

		@Command public void has_parameters(IPrintWriter out,Interpreter interp) {
			out.print(params.length > 0 || meaning.getParameterNames().length > 0);
		}

		public static final CommandSpec parameter_list = CommandSpec.DO;

		@Command public void parameter_list(IPrintWriter out, ScopedInterpreter<ParameterList> interp) {
			String[] parameters = meaning.getParameterNames();
			String[] requiredParameters = meaning.getRequiredParameterNames();
			String dotParameter = meaning.getDotParameterName();

			HashMap<String,String> all = new HashMap<String,String>();
			for (String s : params) {
				String[] keyValue = s.split("=");
				String name = keyValue[0];
				String description = keyValue[1];
				all.put(name, description);
			}
			for (String s : parameters) {
				if (!all.containsKey(s))
					all.put(s, "");
			}
			List<ParameterInfo> infos = new ArrayList<ParameterInfo>();
			for( Map.Entry<String,String> entry : all.entrySet() ) {
				String name = entry.getKey();
				String description = entry.getValue();
				boolean isOptional = !contains(name, requiredParameters);
				boolean isDotParameter = name.equals(dotParameter);
				infos.add(new ParameterInfo(name, description, isOptional, isDotParameter));
			}
			out.print(interp.getArg(new ParameterList(infos),"do"));
		}

		private boolean contains(String name, String[] names) {
			for (String s : names)
				if (s.equals(name))
					return true;
			return false;
		}

		public static final CommandSpec see_also = CommandSpec.DO;

		@Command public void see_also(IPrintWriter out, ScopedInterpreter<StringList> interp) {
			out.print(interp.getArg(new StringList(Arrays.asList(seeAlso)),"do"));
		}

		@Command public void requires(IPrintWriter out, Interpreter interp) {
			out.print( meaning.getRequiredNamespaces().iterator().next() );
		}

		@Command public void adds_namespace(IPrintWriter out, Interpreter interp) {
			out.print( meaning.addsNamespace() != null );
		}

		@Command public void added_namespace(IPrintWriter out, Interpreter interp) {
			out.print( meaning.addsNamespace() );
		}

		@Command public void binary_details(IPrintWriter out,Interpreter interp) {
			out.print(meaning.getMethod());
		}

		public static final CommandSpec related_commands = CommandSpec.DO;

		@Command public void related_commands(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace.Commands> interp)
			throws IOException, ServletException, CompileException
		{
			List<MacroSourceNamespace.CommandInfo> commands = relatedCommands();
			Collections.sort(commands, MacroSourceNamespace.CommandInfo.MACRO_NAME_COMPARATOR);
			Object block = interp.getArg(new MacroSourceNamespace.Commands(commands),"do");
			out.print(block);
		}

		private List<MacroSourceNamespace.CommandInfo> relatedCommands() {
			List<MacroSourceNamespace.CommandInfo> commands = new ArrayList<MacroSourceNamespace.CommandInfo>();
			Class c = meaning.getMethod().getDeclaringClass();
			for (Method method : c.getMethods()) {
				if (method.getAnnotation(Command.class) != null) {
					Meaning m = site.getProgram().getMeaning(c.getName() + '.' + method.getName());
					if (m != null)
						commands.add(new MacroSourceNamespace.CommandInfo(m, null, null));
				}
			}
			return commands;
		}
	}

	@Namespace (
		name = "parameter_list",
		global = true
	)
	public static final class ParameterList extends ListSequence<ParameterInfo> {
		
		public ParameterList(List<ParameterInfo> elements) {
			super(elements);
		}

		public static final CommandSpec current_parameter = CommandSpec.DO;

		@Command public void current_parameter(IPrintWriter out,ScopedInterpreter<ParameterInfo> interp) {
			out.print(interp.getArg(get(),"do"));
		}
	}

	@Namespace (
		name = "parameter_info",
		global = true
	)
	public static final class ParameterInfo {

		private final String name;
		private final String description;
		private final boolean isOptional;
		private final boolean isDotParameter;

		public ParameterInfo(String name, String description, boolean isOptional, boolean isDotParameter) {
			this.name = name;
			this.description = description;
			this.isOptional = isOptional;
			this.isDotParameter = isDotParameter;
		}

		@Command("name") public void _name(IPrintWriter out,Interpreter interp) {
			out.print(name);
		}

		@Command("description") public void _description(IPrintWriter out,Interpreter interp) {
			out.print(description);
		}

		@Command public void is_optional(IPrintWriter out,Interpreter interp) {
			out.print(isOptional);
		}
		
		@Command public void is_dot_parameter(IPrintWriter out,Interpreter interp) {
			out.print(isDotParameter);
		}
	}

}