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

org.snapscript.core.convert.InterfaceCollector Maven / Gradle / Ivy

package org.snapscript.core.convert;

import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.snapscript.core.Any;
import org.snapscript.core.Context;
import org.snapscript.core.EntityCache;
import org.snapscript.core.module.Module;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.type.Type;
import org.snapscript.core.type.TypeExtractor;

public class InterfaceCollector {

   private final EntityCache cache;
   private final Class[] include;
   private final Class[] empty;
   
   public InterfaceCollector(Class... include) {
      this.cache = new EntityCache();
      this.empty = new Class[]{};
      this.include = include;
   }
   
   public Class[] collect(Scope scope) {
      Type type = scope.getHandle();
      
      if(type != null) {
         return collect(type);
      }
      return empty;
   }
   
   public Class[] collect(Type type) {
      Class[] interfaces = cache.fetch(type);
      
      if(interfaces == null) {
         Set types = traverse(type);
         Class[] result = convert(types);
         
         cache.cache(type, result);
         return result;
      }
      return interfaces;
   }
   
   public Class[] collect(Class... types) {
      if(types.length > 0) {
         Set interfaces = new HashSet();
         
         for(Class entry : types) {
            if(entry != null) {
               if(entry.isInterface()) {
                  interfaces.add(entry);
               }
            }
         }
         return convert(interfaces);
      }
      return empty;
   }
   
   private Set traverse(Type type) {
      Module module = type.getModule();
      Context context = module.getContext();
      TypeExtractor extractor = context.getExtractor();
      Set types = extractor.getTypes(type);
      
      if(!types.isEmpty()) {
         Set interfaces = new HashSet();
      
         for(Type entry : types) {
            Class part = entry.getType();
            
            if(part != null) {
               int modifiers = part.getModifiers();
               
               if(part.isInterface() && Modifier.isPublic(modifiers)) {
                  interfaces.add(part);
               }
            }
         }
         for(Class entry : include) {
            interfaces.add(entry);
         }
         interfaces.add(Any.class);
         return interfaces;
      }
      return Collections.singleton(Any.class);
   }

   private Class[] convert(Set types) {
      int size = types.size();

      if(size > 0) {
         Class[] array = new Class[size];
         int index = 0;

         for(Class type : types) {
            array[index++] = type;
         }
         return array;
      }
      return empty;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy