All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.easydoc.semantics.EasydocSemantics Maven / Gradle / Ivy

package com.github.easydoc.semantics;

import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.github.easydoc.model.Directive;
import com.github.easydoc.model.Doc;
import com.github.easydoc.model.Model;
import com.github.easydoc.semantics.directiverule.DirectiveRule;
import com.github.easydoc.semantics.directiverule.IncludeDirectiveRule;
import com.github.easydoc.semantics.exception.EasydocSemanticException;
import com.github.easydoc.semantics.paramrule.BelongsParamRule;
import com.github.easydoc.semantics.paramrule.FormatParamRule;
import com.github.easydoc.semantics.paramrule.IdParamRule;
import com.github.easydoc.semantics.paramrule.IgnoreParamRule;
import com.github.easydoc.semantics.paramrule.ParamRule;
import com.github.easydoc.semantics.paramrule.WeightParamRule;

public class EasydocSemantics {
	public static class CompilationResult {
		private boolean positive;
		private List errors = new ArrayList();
		private Model model;

		public CompilationResult(boolean positive, Model model) {
			this.positive = positive;
			this.model = model;
		}

		public boolean isPositive() {
			return positive;
		}
		
		public Model getModel() {
			return model;
		}
		
		public void setPositive(boolean value) {
			positive = value;
		}

		public void addError(String message) {
			errors.add(message);
		}
		
		public Collection getErrors() {
			return errors;
		}

		@Override
		public String toString() {
			return String.format("CompilationResult [positive=%s, errors=%s, model=%s]", positive, errors,
					model);
		}
	}
	
	private enum Param {
		ID("id", new IdParamRule()),
		BELONGS("belongs", new BelongsParamRule()),
		WEIGHT("weight", new WeightParamRule()),
		IGNORE("ignore", new IgnoreParamRule()),
		FORMAT("format", new FormatParamRule());
		
		private final String name;
		private final ParamRule rule;
		private String defaultValue;

		private Param(String name, ParamRule paramRule) {
			this.name = name;
			this.rule = paramRule;
		}
		
		public static Param getByName(String name) {
			for(Param e : EnumSet.allOf(Param.class)) {
				if(e.name.equals(name)) {
					return e;
				}
			}
			return null;
		}
		
		public static EnumSet getParamsWithDefaultValues() {
			EnumSet ret = EnumSet.noneOf(Param.class);
			for(Param e : EnumSet.allOf(Param.class)) {
				if(e.getDefaultValue() != null) {
					ret.add(e);
				}
			}
			return ret;
		}

		public String getDefaultValue() {
			return defaultValue;
		}

		public void setDefaultValue(String defaultValue) {
			this.defaultValue = defaultValue;
		}

		public String getName() {
			return name;
		}

		public ParamRule getRule() {
			return rule;
		}
	}
	
	/*@@easydoc-start, id=easydoc-directives, belongs=easydoc-advanced@@
	

Directives

Directives are special tags inside a doc text, which are replaced with some values, depending on a directive meaning. A doc can have any number of directives inside.
Example:

\@\@easydoc-start\@\@

Simple text and a directive: \@\@include, id=doc-to-include\@\@

\@\@easydoc-end\@\@
	

Each directive has a name and parameters. Some parameters may be optional, some may be required. See documentation for a concrete directive. @@easydoc-end@@*/ private enum DirectiveDef { INCLUDE("include", new IncludeDirectiveRule()); private final String name; private final DirectiveRule rule; private DirectiveDef(String name, DirectiveRule rule) { this.name = name; this.rule = rule; } public static DirectiveDef getByName(String name) { for(DirectiveDef d : EnumSet.allOf(DirectiveDef.class)) { if(d.name.equals(name)) { return d; } } return null; } public DirectiveRule getRule() { return rule; } } public void setDefaultFormat(String format) { Param.FORMAT.setDefaultValue(format); } public CompilationResult compileModel(Model model) { CompilationResult result = new CompilationResult(true, model); EnumSet defaultValueParams = Param.getParamsWithDefaultValues(); Iterator rawIter = model.getRawDocs().iterator(); while(rawIter.hasNext()) { Doc doc = rawIter.next(); rawIter.remove(); model.getDocTree().addRoot(doc); try { //try to apply default values for(Param p : defaultValueParams) { if(!doc.getParams().containsKey(p.getName())) { doc.getParams().put(p.getName(), p.getDefaultValue()); } } applyDirectives(doc, model); applyParameters(doc, model); } catch(EasydocSemanticException e) { result.setPositive(false); result.addError(e.getMessage()); } } model.getDocTree().sort(); return result; } private void applyDirectives(Doc doc, Model model) throws EasydocSemanticException { for(Directive directive : doc.getDirectives()) { DirectiveDef ddef = DirectiveDef.getByName(directive.getName()); if(ddef == null) throw new EasydocSemanticException(doc, "Unknown directive: '" + directive.getName() + "'"); DirectiveRule drule = ddef.getRule(); for(String rparam : drule.getRequiredParams()) { if(!directive.getParams().containsKey(rparam)) { throw new EasydocSemanticException(doc, directive, "Required parameter '" + rparam + "' is absent."); } } //TODO: check for undefined params ValidationResult result = drule.validate(directive, doc, model); if(!result.isPositive()) { throw new EasydocSemanticException(doc, result); //TODO: return negative result instead } drule.run(directive, doc, model, result); } } private void applyParameters(Doc doc, Model model) throws EasydocSemanticException { for(Map.Entry paramEntry : doc.getParams().entrySet()) { Param param = Param.getByName(paramEntry.getKey()); if(param == null) throw new EasydocSemanticException(doc, "Unknown parameter: '" + paramEntry.getKey() + "'"); ParamRule paramRule = param.getRule(); if(paramRule.requiresValue() && paramEntry.getValue() == null) throw new EasydocSemanticException(doc, "Parameter '" + paramEntry.getKey() + "': value is required"); ValidationResult result = paramRule.validate(paramEntry.getValue(), doc, model); if(!result.isPositive()) { throw new EasydocSemanticException(doc, result); //TODO: return negative result instead } paramRule.run(paramEntry.getValue(), doc, model, result); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy