Package javarag.impl.reg

Source Code of javarag.impl.reg.BasicAttributeRegister

package javarag.impl.reg;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;

import javarag.AttributeEvaluator;
import javarag.AttributeRegister;
import javarag.Bottom;
import javarag.CacheMode;
import javarag.Cached;
import javarag.Circular;
import javarag.Collected;
import javarag.Inherited;
import javarag.Module;
import javarag.NonTerminal;
import javarag.Procedural;
import javarag.Synthesized;
import javarag.TreeTraverser;
import javarag.Types;
import javarag.impl.TreeStructure;

public class BasicAttributeRegister implements AttributeRegister {
  private final EvaluatorBuilder builder;
  private final Set<String> collectionAttributes;
  private final Set<String> attributeNames;

  public BasicAttributeRegister() {
    builder = new EvaluatorBuilder();
    collectionAttributes = new HashSet<>();
    attributeNames = new HashSet<>();
  }

  @Override
  public void register(Class<?>... attributeModules) {
    for (Class<?> module : attributeModules) {
      addDeclarations(module);
    }
    for (Class<?> module : attributeModules) {
      addDefinitions(module);
    }
  }

  private void addDeclarations(Class<?> module) {
    Class<?>[] interfaces = extractModuleImpls(module);
    for (Class<?> iface : interfaces) {
      for (Method decl : iface.getMethods()) {
        String name = decl.getName();
        if (!attributeNames.contains(name)) {
          if (hasAnnotation(decl, Inherited.class)) {
            builder.createInherited(name);
            attributeNames.add(name);
          } else if (hasAnnotation(decl, Synthesized.class)) {
            builder.createSynthesized(name);
            attributeNames.add(name);
          } else if (hasAnnotation(decl, Procedural.class)) {
            builder.createProcedural(name);
            attributeNames.add(name);
          } else if (hasAnnotation(decl, Collected.class)) {
            builder.createCollected(name);
            attributeNames.add(name);
            collectionAttributes.add(name);
          }
          Cached cached = decl.getAnnotation(Cached.class);
          if (cached != null && cached.value() == CacheMode.ALWAYS) {
            builder.setCached(name);
          }
          if (hasAnnotation(decl, Circular.class)) {
            builder.setCircular(name);
          }
          if (hasAnnotation(decl, NonTerminal.class)) {
            builder.setNonTerminal(name);
          }
        }
      }
    }
  }

  private void addDefinitions(Class<?> module) {
    for (Method def : module.getMethods()) {
      Class<?> declaringClass = def.getDeclaringClass();
      if (Module.class != declaringClass && Module.class.isAssignableFrom(declaringClass)) {
        Bottom bottom = def.getAnnotation(Bottom.class);
        if (bottom != null) {
          String name = bottom.value();
          if (name.equals("")) {
            name = def.getName();
          }
          builder.addBottom(name, def);
        } else {
          if (collectionAttributes.contains(def.getName()) && def.getParameterTypes().length == 2) {
            builder.addContribution(def.getName(), def);
          } else {
            builder.addDefinition(def.getName(), def);
          }
        }
      }
    }
  }

  private boolean hasAnnotation(Method decl, Class<? extends Annotation> annotation) {
    return decl.getAnnotation(annotation) != null;
  }

  private Class<?>[] extractModuleImpls(Class<?> klass) {
    Type module = Types.findSuperclass(klass, Module.class);
    Type[] params = Types.getTypeParameters(module);
    return Types.getTypeAsInterfaces(params[0]);
  }

  @Override
  public <T> AttributeEvaluator getEvaluator(T tree, TreeTraverser<T> traverser) {
    return builder.build(new TreeStructure(tree, traverser));
  }

}
TOP

Related Classes of javarag.impl.reg.BasicAttributeRegister

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.