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

org.deephacks.tools4j.config.internal.core.query.ConfigIndex Maven / Gradle / Ivy

There is a newer version: 0.15.0
Show newest version
package org.deephacks.tools4j.config.internal.core.query;

import com.googlecode.cqengine.attribute.Attribute;
import com.googlecode.cqengine.attribute.MultiValueNullableAttribute;
import com.googlecode.cqengine.attribute.SimpleNullableAttribute;
import org.deephacks.tools4j.config.Index;
import org.deephacks.tools4j.config.model.Schema;
import org.deephacks.tools4j.config.model.Schema.AbstractSchemaProperty;
import org.deephacks.tools4j.config.model.Schema.SchemaProperty;
import org.deephacks.tools4j.config.model.Schema.SchemaPropertyList;
import org.deephacks.tools4j.config.model.Schema.SchemaPropertyRef;
import org.deephacks.tools4j.config.model.Schema.SchemaPropertyRefList;
import org.deephacks.tools4j.config.model.Schema.SchemaPropertyRefMap;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ConfigIndex {
    private Class cls;
    private HashMap> attributes = new HashMap<>();

    public ConfigIndex(Schema schema) {
        for(AbstractSchemaProperty property : schema.getIndexed()) {
            String propertyName = property.getName();
            Class type = getType(property);
            if(Number.class.isAssignableFrom(type)) {
                NumberAttribute attr = new NumberAttribute(propertyName);
                attributes.put(propertyName, attr);
            } else if (Collection.class.isAssignableFrom(type)) {
                MultiObjectAttribute attr = new MultiObjectAttribute(propertyName);
                attributes.put(propertyName, attr);
            } else if (Map.class.isAssignableFrom(type)) {
                MultiObjectAttribute attr = new MultiObjectAttribute(propertyName);
                attributes.put(propertyName, attr);
            } else {
                ObjectAttribute attr = new ObjectAttribute(propertyName);
                attributes.put(propertyName, attr);
            }
        }
    }
    private Class getType(final AbstractSchemaProperty property) {
        if (property instanceof SchemaProperty) {
            return ((SchemaProperty) property).getClassType();
        } else if (property instanceof SchemaPropertyList) {
            return  ((SchemaPropertyList) property).getClassCollectionType();
        } else if (property instanceof SchemaPropertyRef) {
            return String.class;
        } else if (property instanceof SchemaPropertyRefList ||
                property instanceof SchemaPropertyRefMap) {
            return ArrayList.class;
        } else {
            throw new IllegalArgumentException("Unrecognized property");
        }
    }

    public Attribute get(String field) {
        return attributes.get(field);
    }

    public List get() {
        List attrs = new ArrayList<>();
        for(Attribute att : attributes.values()){
            attrs.add(att);
        }
        return attrs;
    }

    private List getIndexedFields(Class cls) {
        List fields = new ArrayList<>();
        for(final Field field : cls.getDeclaredFields()) {
            field.setAccessible(true);
            if(field.getAnnotation(Index.class) != null) {
                fields.add(field);
            }
        }
        return fields;
    }

    static final class ObjectAttribute extends SimpleNullableAttribute {
        private final String field;

        public ObjectAttribute(String field) {
            this.field = field;
        }

        @Override
        public Object getValue(ConfigIndexFields data) {
            return data.fields.get(field);
        }
    }

    static final class MultiObjectAttribute extends MultiValueNullableAttribute {
        private final String field;

        public MultiObjectAttribute(String field) {
            super(field, false);
            this.field = field;
        }

        @Override
        public List getNullableValues(ConfigIndexFields data) {
            Object o = data.fields.get(field);
            if(o == null) {
                return null;
            }
            Class cls = o.getClass();
            if(Collection.class.isAssignableFrom(cls)) {
                return (List) o;
            } else if(Map.class.isAssignableFrom(cls)) {
                ArrayList values = new ArrayList<>();
                for(Object value : ((Map)o).values()) {
                    values.add(value);
                }
                return values;
            } else {
                throw new IllegalArgumentException("Could not get correct collection from ["+o+"]");
            }
        }
    }

    static final class NumberAttribute extends SimpleNullableAttribute {
        private final String field;

        public NumberAttribute(String field) {
            this.field = field;
        }

        @Override
        public Number getValue(ConfigIndexFields data) {
            return (Number) data.fields.get(field);
        }
    }

}