package com.thinkaurelius.titan.graphdb.blueprints;

import com.thinkaurelius.titan.diskstorage.keycolumnvalue.StoreFeatures;
import com.thinkaurelius.titan.graphdb.configuration.GraphDatabaseConfiguration;
import com.tinkerpop.blueprints.Features;

/**
 * Blueprint's features of a TitanGraph.
 *
 * @author Matthias Broecheler (me@matthiasb.com)
 */

public class TitanFeatures {

    private static Features getBaselineTitanFeatures() {
        Features features = new Features();
        features.supportsDuplicateEdges = true;
        features.supportsSelfLoops = true;
        features.supportsSerializableObjectProperty = true;
        features.supportsBooleanProperty = true;
        features.supportsDoubleProperty = true;
        features.supportsFloatProperty = true;
        features.supportsIntegerProperty = true;
        features.supportsPrimitiveArrayProperty = true;
        features.supportsUniformListProperty = true;
        features.supportsMixedListProperty = true;
        features.supportsLongProperty = true;
        features.supportsMapProperty = true;
        features.supportsStringProperty = true;
        features.ignoresSuppliedIds = true;
        features.isPersistent = true;
        features.isWrapper = false;
        features.supportsIndices = false;
        features.supportsVertexIndex = false;
        features.supportsEdgeIndex = false;
        features.supportsKeyIndices = true;
        features.supportsVertexKeyIndex = false;
        features.supportsEdgeKeyIndex = false;
        features.supportsEdgeIteration = false;
        features.supportsVertexIteration = false;
        features.supportsVertexProperties = true;
        features.supportsEdgeProperties = true;
        features.supportsEdgeRetrieval = true;
        features.supportsTransactions = true;
        features.supportsThreadedTransactions = true;
        features.checkCompliance();
        return features;
    }

    public static Features getFeatures(GraphDatabaseConfiguration config, StoreFeatures storageFeatures) {
        Features features = TitanFeatures.getBaselineTitanFeatures();
        features.supportsSerializableObjectProperty = config.hasSerializeAll();
        if (storageFeatures != null) {
            if (storageFeatures.hasScan()) {
                features.supportsVertexIteration = true;
                features.supportsEdgeIteration = true;
            }
        }
        return features;
    }

}

@@ -241,16 +241,106 @@
 eatures;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport java.lang.reflect.Field;
 %0A%0A/**%0A *
@@ -466,16 +466,113 @@
 ures %7B%0A%0A
+    private static final Logger log =%0A            LoggerFactory.getLogger(TitanFeatures.class);%0A%0A
     priv
@@ -2052,60 +2052,1003 @@
     
-features.checkCompliance();%0A        return features;
+setIfExists(features, %22supportsThreadIsolatedTransactions%22, true);%0A        features.checkCompliance();%0A        return features;%0A    %7D%0A%0A    private static void setIfExists(Features features, String fieldName, boolean value) %7B%0A%0A        final Class%3C?%3E requiredFieldType = Boolean.class;%0A        final Class%3C?%3E fc = features.getClass();%0A        try %7B%0A            Field f = fc.getField(fieldName);%0A            if (!requiredFieldType.equals(f.getType())) %7B%0A                log.debug(%22Field %7B%7D.%7B%7D has type %7B%7D (but type %7B%7D was expected)%22,%0A                        fc, fieldName, f.getType(), requiredFieldType);%0A                return;%0A            %7D%0A            f.set(features, value);%0A            log.debug(%22Set %7B%7D.%7B%7D to %7B%7D%22, fc, fieldName, value);%0A        %7D catch (NoSuchFieldException e) %7B%0A            log.debug(%22Field %7B%7D.%7B%7D could not be found%22, fc, fieldName, e);%0A        %7D catch (IllegalAccessException e) %7B%0A            log.warn(%22Unable to reflectively customize %7B%7D.%7B%7D%22, fc, fieldName, e);%0A        %7D
 %0A   

Enable BP supportsThreadIsolatedTransactions