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