// Copyright 2017 JanusGraph Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package org.janusgraph.graphdb.vertices; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import org.janusgraph.core.*; import org.janusgraph.graphdb.internal.AbstractElement; import org.janusgraph.graphdb.internal.ElementLifeCycle; import org.janusgraph.graphdb.internal.InternalVertex; import org.janusgraph.graphdb.query.vertex.VertexCentricQueryBuilder; import org.janusgraph.graphdb.transaction.StandardJanusGraphTx; import org.janusgraph.graphdb.types.VertexLabelVertex; import org.janusgraph.graphdb.types.system.BaseLabel; import org.janusgraph.graphdb.types.system.BaseVertexLabel; import org.janusgraph.graphdb.util.ElementHelper; import org.apache.tinkerpop.gremlin.structure.Direction; import org.apache.tinkerpop.gremlin.structure.Edge; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import java.util.Iterator; public abstract class AbstractVertex extends AbstractElement implements InternalVertex, Vertex { private final StandardJanusGraphTx tx; protected AbstractVertex(StandardJanusGraphTx tx, long id) { super(id); assert tx != null; this.tx = tx; } @Override public final InternalVertex it() { if (tx.isOpen()) return this; InternalVertex next = (InternalVertex) tx.getNextTx().getVertex(longId()); if (next == null) throw InvalidElementException.removedException(this); else return next; } @Override public final StandardJanusGraphTx tx() { return tx.isOpen() ? tx : tx.getNextTx(); } @Override public long getCompareId() { if (tx.isPartitionedVertex(this)) return tx.getIdInspector().getCanonicalVertexId(longId()); else return longId(); } @Override public String toString() { return StringFactory.vertexString(this); } @Override public Object id() { return longId(); } @Override public boolean isModified() { return ElementLifeCycle.isModified(it().getLifeCycle()); } protected final void verifyAccess() { if (isRemoved()) { throw InvalidElementException.removedException(this); } } /* --------------------------------------------------------------- * Changing Edges * --------------------------------------------------------------- */ @Override public synchronized void remove() { verifyAccess(); // if (isRemoved()) return; //Remove() is idempotent Iterator<JanusGraphRelation> iter = it().query().noPartitionRestriction().relations().iterator(); while (iter.hasNext()) { iter.next(); iter.remove(); } //Remove all system types on the vertex for (JanusGraphRelation r : it().query().noPartitionRestriction().system().relations()) { r.remove(); } } /* --------------------------------------------------------------- * JanusGraphRelation Iteration/Access * --------------------------------------------------------------- */ @Override public String label() { return vertexLabel().name(); } protected Vertex getVertexLabelInternal() { return Iterables.getOnlyElement(tx().query(this).noPartitionRestriction().type(BaseLabel.VertexLabelEdge).direction(Direction.OUT).vertices(),null); } @Override public VertexLabel vertexLabel() { Vertex label = getVertexLabelInternal(); if (label==null) return BaseVertexLabel.DEFAULT_VERTEXLABEL; else return (VertexLabelVertex)label; } @Override public VertexCentricQueryBuilder query() { verifyAccess(); return tx().query(this); } @Override public <O> O valueOrNull(PropertyKey key) { return (O)property(key.name()).orElse(null); } /* --------------------------------------------------------------- * Convenience Methods for JanusGraphElement Creation * --------------------------------------------------------------- */ public<V> JanusGraphVertexProperty<V> property(final String key, final V value, final Object... keyValues) { JanusGraphVertexProperty<V> p = tx().addProperty(it(), tx().getOrCreatePropertyKey(key, value), value); ElementHelper.attachProperties(p,keyValues); return p; } @Override public <V> JanusGraphVertexProperty<V> property(final VertexProperty.Cardinality cardinality, final String key, final V value, final Object... keyValues) { JanusGraphVertexProperty<V> p = tx().addProperty(cardinality, it(), tx().getOrCreatePropertyKey(key, value), value); ElementHelper.attachProperties(p,keyValues); return p; } @Override public JanusGraphEdge addEdge(String label, Vertex vertex, Object... keyValues) { Preconditions.checkArgument(vertex instanceof JanusGraphVertex,"Invalid vertex provided: %s",vertex); JanusGraphEdge edge = tx().addEdge(it(), (JanusGraphVertex) vertex, tx().getOrCreateEdgeLabel(label)); ElementHelper.attachProperties(edge,keyValues); return edge; } public Iterator<Edge> edges(Direction direction, String... labels) { return (Iterator)query().direction(direction).labels(labels).edges().iterator(); } public <V> Iterator<VertexProperty<V>> properties(String... keys) { return (Iterator)query().direction(Direction.OUT).keys(keys).properties().iterator(); } public Iterator<Vertex> vertices(final Direction direction, final String... edgeLabels) { return (Iterator)query().direction(direction).labels(edgeLabels).vertices().iterator(); } }