<commit_before>package com.tinkerpop.blueprints.impls.orient;

import com.orientechnologies.orient.core.db.graph.OGraphDatabase;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.index.OPropertyIndexDefinition;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OProperty;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Index;
import com.tinkerpop.blueprints.IndexableGraph;
import com.tinkerpop.blueprints.KeyIndexableGraph;
import com.tinkerpop.blueprints.MetaGraph;
import com.tinkerpop.blueprints.Parameter;
import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.ExceptionFactory;
import com.tinkerpop.blueprints.util.PropertyFilteredIterable;
import com.tinkerpop.blueprints.util.StringFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * A Blueprints implementation of the graph database OrientDB (http://www.orientechnologies.com)
 *
 * @author <NAME> (http://www.orientechnologies.com)
 */
public abstract class OrientBaseGraph implements IndexableGraph, MetaGraph<OGraphDatabase>, KeyIndexableGraph {
    /**
   * 
   */
  private static final String CLASS_PREFIX = "class:";

    protected final static String ADMIN = "admin";

    private String url;
    private String username;
    private String password;

    private static final ThreadLocal<OrientGraphContext> threadContext = new ThreadLocal<OrientGraphContext>();
    private static final List<OrientGraphContext> contexts = new ArrayList<OrientGraphContext>();

    /**
     * Constructs a new object using an existent OGraphDatabase instance.
     *
     * @param iDatabase Underlying OGraphDatabase object to attach
     */
    public OrientBaseGraph(final OGraphDatabase iDatabase) {
        reuse(iDatabase);
    }

    public OrientBaseGraph(final String url) {
        this(url, ADMIN, ADMIN);
    }

    public OrientBaseGraph(final String url, final String username, final String password) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.openOrCreate();
    }

    @SuppressWarnings("unchecked")
    public <T extends Element> Index<T> createIndex(final String indexName, final Class<T> indexClass, final Parameter... indexParameters) {
        final OrientGraphContext context = getContext(true);

        if (getRawGraph().getTransaction().isActive())
            stopTransaction(Conclusion.SUCCESS);

        synchronized (contexts) {
            if (context.manualIndices.containsKey(indexName))
                throw ExceptionFactory.indexAlreadyExists(indexName);

            final OrientIndex<? extends OrientElement> index = new OrientIndex<OrientElement>(this, indexName, indexClass, null);

            // ADD THE INDEX IN ALL CURRENT CONTEXTS
            for (OrientGraphContext ctx : contexts)
                ctx.manualIndices.put(index.getIndexName(), index);

            // SAVE THE CONFIGURATION INTO THE GLOBAL CONFIG
            saveIndexConfiguration();

            return (Index<T>) index;
        }
    }

    @SuppressWarnings("unchecked")
    public <T extends Element> Index<T> getIndex(final String indexName, final Class<T> indexClass) {
        final OrientGraphContext context = getContext(true);
        Index<? extends Element> index = context.manualIndices.get(indexName);
        if (null == index) {
            return null;
        }

        if (indexClass.isAssignableFrom(index.getIndexClass()))
            return (Index<T>) index;
        else
            throw ExceptionFactory.indexDoesNotSupportClass(indexName, indexClass);
    }

    public Iterable<Index<? extends Element>> getIndices() {
        final OrientGraphContext context = getContext(true);
        final List<Index<? extends Element>> list = new ArrayList<Index<? extends Element>>();
        for (Index<?> index : context.manualIndices.values()) {
            list.add(index);
        }
        return list;
    }

    protected Iterable<OrientIndex<? extends OrientElement>> getManualIndices() {
        return getContext(true).manualIndices.values();
    }

    public void dropIndex(final String indexName) {
        if (getRawGraph().getTransaction().isActive())
            stopTransaction(Conclusion.SUCCESS);

        try {
            synchronized (contexts) {
                for (OrientGraphContext ctx : contexts) {
                    ctx.manualIndices.remove(indexName);
                }
            }

            getRawGraph().getMetadata().getIndexManager().dropIndex(indexName);
            saveIndexConfiguration();
        } catch (Exception e) {
            this.stopTransaction(Conclusion.FAILURE);
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public Vertex addVertex(final Object id) {
        String className = null; 
        if( id != null && id instanceof String && id.toString().startsWith(CLASS_PREFIX))
          // GET THE CLASS NAME
          className = id.toString().substring( CLASS_PREFIX.length() );
        
        final OGraphDatabase db = getRawGraph();
        this.autoStartTransaction();
        final OrientVertex vertex = new OrientVertex(this, db.createVertex(className));
        vertex.save();
        return vertex;
    }

    public Edge addEdge(final Object id, final Vertex outVertex, final Vertex inVertex, final String label) {
        final OGraphDatabase db = getRawGraph();
        this.autoStartTransaction();
        final ODocument edgeDoc = db.createEdge(((OrientVertex) outVertex).getRawElement(), ((OrientVertex) inVertex).getRawElement());
        final OrientEdge edge = new OrientEdge(this, edgeDoc, label);

        // SAVE THE VERTICES TO ASSURE THEY ARE IN TX
        db.save(((OrientVertex) outVertex).getRawElement());
        db.save(((OrientVertex) inVertex).getRawElement());
        edge.save();
        return edge;
    }

    public Vertex getVertex(final Object id) {
        if (null == id)
            throw ExceptionFactory.vertexIdCanNotBeNull();

        ORID rid;
        if (id instanceof ORID)
            rid = (ORID) id;
        else {
            try {
                rid = new ORecordId(id.toString());
            } catch (IllegalArgumentException iae) {
                // orientdb throws IllegalArgumentException: Argument 'xxxx' is not a RecordId in form of string. Format must be: <cluster-id>:<cluster-position>
                return null;<commit_msg>Added support for sub-types even for edges by passing "class:<x>" to addEdge()<commit_after>package com.tinkerpop.blueprints.impls.orient;

import com.orientechnologies.orient.core.db.graph.OGraphDatabase;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.index.OPropertyIndexDefinition;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OProperty;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Index;
import com.tinkerpop.blueprints.IndexableGraph;
import com.tinkerpop.blueprints.KeyIndexableGraph;
import com.tinkerpop.blueprints.MetaGraph;
import com.tinkerpop.blueprints.Parameter;
import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.ExceptionFactory;
import com.tinkerpop.blueprints.util.PropertyFilteredIterable;
import com.tinkerpop.blueprints.util.StringFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * A Blueprints implementation of the graph database OrientDB (http://www.orientechnologies.com)
 *
 * @author <NAME> (http://www.orientechnologies.com)
 */
public abstract class OrientBaseGraph implements IndexableGraph, MetaGraph<OGraphDatabase>, KeyIndexableGraph {
    /**
   * 
   */
  private static final String CLASS_PREFIX = "class:";

    protected final static String ADMIN = "admin";

    private String url;
    private String username;
    private String password;

    private static final ThreadLocal<OrientGraphContext> threadContext = new ThreadLocal<OrientGraphContext>();
    private static final List<OrientGraphContext> contexts = new ArrayList<OrientGraphContext>();

    /**
     * Constructs a new object using an existent OGraphDatabase instance.
     *
     * @param iDatabase Underlying OGraphDatabase object to attach
     */
    public OrientBaseGraph(final OGraphDatabase iDatabase) {
        reuse(iDatabase);
    }

    public OrientBaseGraph(final String url) {
        this(url, ADMIN, ADMIN);
    }

    public OrientBaseGraph(final String url, final String username, final String password) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.openOrCreate();
    }

    @SuppressWarnings("unchecked")
    public <T extends Element> Index<T> createIndex(final String indexName, final Class<T> indexClass, final Parameter... indexParameters) {
        final OrientGraphContext context = getContext(true);

        if (getRawGraph().getTransaction().isActive())
            stopTransaction(Conclusion.SUCCESS);

        synchronized (contexts) {
            if (context.manualIndices.containsKey(indexName))
                throw ExceptionFactory.indexAlreadyExists(indexName);

            final OrientIndex<? extends OrientElement> index = new OrientIndex<OrientElement>(this, indexName, indexClass, null);

            // ADD THE INDEX IN ALL CURRENT CONTEXTS
            for (OrientGraphContext ctx : contexts)
                ctx.manualIndices.put(index.getIndexName(), index);

            // SAVE THE CONFIGURATION INTO THE GLOBAL CONFIG
            saveIndexConfiguration();

            return (Index<T>) index;
        }
    }

    @SuppressWarnings("unchecked")
    public <T extends Element> Index<T> getIndex(final String indexName, final Class<T> indexClass) {
        final OrientGraphContext context = getContext(true);
        Index<? extends Element> index = context.manualIndices.get(indexName);
        if (null == index) {
            return null;
        }

        if (indexClass.isAssignableFrom(index.getIndexClass()))
            return (Index<T>) index;
        else
            throw ExceptionFactory.indexDoesNotSupportClass(indexName, indexClass);
    }

    public Iterable<Index<? extends Element>> getIndices() {
        final OrientGraphContext context = getContext(true);
        final List<Index<? extends Element>> list = new ArrayList<Index<? extends Element>>();
        for (Index<?> index : context.manualIndices.values()) {
            list.add(index);
        }
        return list;
    }

    protected Iterable<OrientIndex<? extends OrientElement>> getManualIndices() {
        return getContext(true).manualIndices.values();
    }

    public void dropIndex(final String indexName) {
        if (getRawGraph().getTransaction().isActive())
            stopTransaction(Conclusion.SUCCESS);

        try {
            synchronized (contexts) {
                for (OrientGraphContext ctx : contexts) {
                    ctx.manualIndices.remove(indexName);
                }
            }

            getRawGraph().getMetadata().getIndexManager().dropIndex(indexName);
            saveIndexConfiguration();
        } catch (Exception e) {
            this.stopTransaction(Conclusion.FAILURE);
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public Vertex addVertex(final Object id) {
        String className = null; 
        if( id != null && id instanceof String && id.toString().startsWith(CLASS_PREFIX))
          // GET THE CLASS NAME
          className = id.toString().substring( CLASS_PREFIX.length() );
        
        final OGraphDatabase db = getRawGraph();
        this.autoStartTransaction();
        final OrientVertex vertex = new OrientVertex(this, db.createVertex(className));
        vertex.save();
        return vertex;
    }

    public Edge addEdge(final Object id, final Vertex outVertex, final Vertex inVertex, final String label) {
        String className = null; 
        if( id != null && id instanceof String && id.toString().startsWith(CLASS_PREFIX))
          // GET THE CLASS NAME
          className = id.toString().substring( CLASS_PREFIX.length() );

      
        final OGraphDatabase db = getRawGraph();
        this.autoStartTransaction();
        final ODocument edgeDoc = db.createEdge(((OrientVertex) outVertex).getRawElement(), ((OrientVertex) inVertex).getRawElement(), className);
        final OrientEdge edge = new OrientEdge(this, edgeDoc, label);

        // SAVE THE VERTICES TO ASSURE THEY ARE IN TX
        db.save(((OrientVertex) outVertex).getRawElement());
        db.save(((OrientVertex) inVertex).getRawElement());
        edge.save();
        return edge;
    }

    public Vertex getVertex(final Object id) {
        if (null == id)
            throw ExceptionFactory.vertexIdCanNotBeNull();

        ORID rid;
        if (id instanceof ORID)
            rid = (ORID) id;
        else {
            try {
                rid = new ORecordId(id.toString());
            } catch (IllegalArgumentException iae) {
                // orientdb throws IllegalArgumentException: Argument 'xxxx' is not a RecordId in form of string. Format must be: <cluster-id>:<cluster-position>
                return null;
{'fraction_non_alphanumeric': 0.0986943703495718, 'fraction_numerical': 0.0, 'mean_word_length': 3.054354012521343, 'pattern_counts': {'":': 0, '<': 60, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4745348', 'n_tokens_mistral': 3858, 'n_tokens_neox': 3736, 'n_words': 912}