You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2017/11/12 18:14:44 UTC
[35/42] atlas git commit: ATLAS-2251: Remove TypeSystem and related
implementation, to avoid unncessary duplicate of type details in cache
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index 7f24d5a..03a86f4 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -24,7 +24,6 @@ import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException;
import org.apache.atlas.SortOrder;
import org.apache.atlas.annotation.GraphTransaction;
-import org.apache.atlas.discovery.graph.DefaultGraphPersistenceStrategy;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
@@ -44,7 +43,6 @@ import org.apache.atlas.query.QueryParser;
import org.apache.atlas.query.QueryProcessor;
import org.apache.atlas.query.SelectExpressionHelper;
import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.MetadataRepository;
import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
import org.apache.atlas.repository.graph.GraphHelper;
import org.apache.atlas.repository.graphdb.AtlasGraph;
@@ -70,9 +68,6 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
-import scala.Option;
-import scala.util.Either;
-import scala.util.parsing.combinator.Parsers.NoSuccess;
import javax.inject.Inject;
import javax.script.Bindings;
@@ -104,7 +99,6 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private static final String DEFAULT_SORT_ATTRIBUTE_NAME = "name";
private final AtlasGraph graph;
- private final DefaultGraphPersistenceStrategy graphPersistenceStrategy;
private final EntityGraphRetriever entityRetriever;
private final AtlasGremlinQueryProvider gremlinQueryProvider;
private final AtlasTypeRegistry typeRegistry;
@@ -116,11 +110,10 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private final UserProfileService userProfileService;
@Inject
- EntityDiscoveryService(MetadataRepository metadataRepository, AtlasTypeRegistry typeRegistry,
+ EntityDiscoveryService(AtlasTypeRegistry typeRegistry,
AtlasGraph graph, GraphBackedSearchIndexer indexer, SearchTracker searchTracker,
UserProfileService userProfileService) throws AtlasException {
this.graph = graph;
- this.graphPersistenceStrategy = new DefaultGraphPersistenceStrategy(metadataRepository);
this.entityRetriever = new EntityGraphRetriever(typeRegistry);
this.indexer = indexer;
this.searchTracker = searchTracker;
@@ -685,15 +678,14 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private GremlinQuery toGremlinQuery(String query, int limit, int offset) throws AtlasBaseException {
QueryParams params = validateSearchParams(limit, offset);
- Either<NoSuccess, Expression> either = QueryParser.apply(query, params);
+ Expression expression = QueryParser.apply(query, params);
- if (either.isLeft()) {
+ if (expression == null) {
throw new AtlasBaseException(DISCOVERY_QUERY_FAILED, query);
}
- Expression expression = either.right().get();
Expression validExpression = QueryProcessor.validate(expression);
- GremlinQuery gremlinQuery = new GremlinTranslator(validExpression, graphPersistenceStrategy).translate();
+ GremlinQuery gremlinQuery = new GremlinTranslator(validExpression).translate();
if (LOG.isDebugEnabled()) {
LOG.debug("Translated Gremlin Query: {}", gremlinQuery.queryStr());
@@ -730,9 +722,9 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
List<List<Object>> values = new ArrayList<>();
// extract select attributes from gremlin query
- Option<SelectExpression> selectExpr = SelectExpressionHelper.extractSelectExpression(query.expr());
- if (selectExpr.isDefined()) {
- List<AliasExpression> aliases = selectExpr.get().toJavaList();
+ SelectExpression selectExpr = SelectExpressionHelper.extractSelectExpression(query.expr());
+ if (selectExpr != null) {
+ List<AliasExpression> aliases = selectExpr.toJavaList();
if (CollectionUtils.isNotEmpty(aliases)) {
for (AliasExpression alias : aliases) {
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java
index 3ae41c8..ae45c5c 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityLineageService.java
@@ -6,9 +6,9 @@
* to you 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
* 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.
@@ -23,6 +23,7 @@ import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.lineage.AtlasLineageInfo;
import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection;
@@ -31,11 +32,17 @@ import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graph.GraphHelper;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1;
import org.apache.atlas.repository.store.graph.v1.EntityGraphRetriever;
+import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.util.AtlasGremlinQueryProvider;
import org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery;
+import org.apache.atlas.v1.model.lineage.SchemaResponse.SchemaDetails;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
@@ -45,21 +52,24 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
@Service
public class EntityLineageService implements AtlasLineageService {
- private static final String INPUT_PROCESS_EDGE = "__Process.inputs";
- private static final String OUTPUT_PROCESS_EDGE = "__Process.outputs";
+ private static final String INPUT_PROCESS_EDGE = "__Process.inputs";
+ private static final String OUTPUT_PROCESS_EDGE = "__Process.outputs";
private final AtlasGraph graph;
private final AtlasGremlinQueryProvider gremlinQueryProvider;
private final EntityGraphRetriever entityRetriever;
+ private final AtlasTypeRegistry atlasTypeRegistry;
@Inject
- EntityLineageService(AtlasTypeRegistry typeRegistry, AtlasGraph atlasGraph) throws DiscoveryException {
- this.graph = atlasGraph;
+ EntityLineageService(AtlasTypeRegistry typeRegistry, AtlasGraph atlasGraph) {
+ this.graph = atlasGraph;
this.gremlinQueryProvider = AtlasGremlinQueryProvider.INSTANCE;
- this.entityRetriever = new EntityGraphRetriever(typeRegistry);
+ this.entityRetriever = new EntityGraphRetriever(typeRegistry);
+ this.atlasTypeRegistry = typeRegistry;
}
@Override
@@ -88,6 +98,53 @@ public class EntityLineageService implements AtlasLineageService {
return lineageInfo;
}
+ @Override
+ @GraphTransaction
+ public SchemaDetails getSchemaForHiveTableByName(final String datasetName) throws AtlasBaseException {
+ if (StringUtils.isEmpty(datasetName)) {
+ // TODO: Complete error handling here
+ throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST);
+ }
+
+ AtlasEntityType hive_table = atlasTypeRegistry.getEntityTypeByName("hive_table");
+
+ Map<String, Object> lookupAttributes = new HashMap<>();
+ lookupAttributes.put("qualifiedName", datasetName);
+ String guid = AtlasGraphUtilsV1.getGuidByUniqueAttributes(hive_table, lookupAttributes);
+
+ return getSchemaForHiveTableByGuid(guid);
+ }
+
+ @Override
+ @GraphTransaction
+ public SchemaDetails getSchemaForHiveTableByGuid(final String guid) throws AtlasBaseException {
+ if (StringUtils.isEmpty(guid)) {
+ throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST);
+ }
+ SchemaDetails ret = new SchemaDetails();
+ AtlasEntityType hive_column = atlasTypeRegistry.getEntityTypeByName("hive_column");
+
+ ret.setDataType(AtlasTypeUtil.toClassTypeDefinition(hive_column));
+
+ AtlasEntity.AtlasEntityWithExtInfo entityWithExtInfo = entityRetriever.toAtlasEntityWithExtInfo(guid);
+ Map<String, AtlasEntity> referredEntities = entityWithExtInfo.getReferredEntities();
+
+ if (MapUtils.isNotEmpty(referredEntities)) {
+ List<Map<String, Object>> rows = referredEntities.entrySet()
+ .stream()
+ .filter(EntityLineageService::isHiveColumn)
+ .map(e -> AtlasTypeUtil.toMap(e.getValue()))
+ .collect(Collectors.toList());
+ ret.setRows(rows);
+ }
+
+ return ret;
+ }
+
+ private static boolean isHiveColumn(Map.Entry<String, AtlasEntity> e) {
+ return StringUtils.equals("hive_column", e.getValue().getTypeName());
+ }
+
private AtlasLineageInfo getLineageInfo(String guid, LineageDirection direction, int depth) throws AtlasBaseException {
Map<String, AtlasEntityHeader> entities = new HashMap<>();
Set<LineageRelation> relations = new HashSet<>();
@@ -108,7 +165,7 @@ public class EntityLineageService implements AtlasLineageService {
continue;
}
- AtlasEntityHeader entity = entityRetriever.toAtlasEntityHeader((AtlasVertex)vertex);
+ AtlasEntityHeader entity = entityRetriever.toAtlasEntityHeader((AtlasVertex) vertex);
if (!entities.containsKey(entity.getGuid())) {
entities.put(entity.getGuid(), entity);
@@ -143,7 +200,7 @@ public class EntityLineageService implements AtlasLineageService {
return ret;
}
- private String getLineageQuery(String entityGuid, LineageDirection direction, int depth) throws AtlasBaseException {
+ private String getLineageQuery(String entityGuid, LineageDirection direction, int depth) {
String lineageQuery = null;
if (direction.equals(LineageDirection.INPUT)) {
@@ -169,18 +226,19 @@ public class EntityLineageService implements AtlasLineageService {
}
private boolean entityExists(String guid) {
- boolean ret = false;
+ boolean ret = false;
Iterator<AtlasVertex> results = graph.query()
- .has(Constants.GUID_PROPERTY_KEY, guid)
- .vertices().iterator();
+ .has(Constants.GUID_PROPERTY_KEY, guid)
+ .vertices().iterator();
while (results.hasNext()) {
AtlasVertex entityVertex = results.next();
List<String> superTypes = GraphHelper.getSuperTypeNames(entityVertex);
- ret = (CollectionUtils.isNotEmpty(superTypes)) ? superTypes.contains(AtlasClient.DATA_SET_SUPER_TYPE) : false;
+ ret = (CollectionUtils.isNotEmpty(superTypes)) && superTypes.contains(AtlasClient.DATA_SET_SUPER_TYPE);
}
return ret;
}
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/main/java/org/apache/atlas/discovery/SearchIndexer.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/SearchIndexer.java b/repository/src/main/java/org/apache/atlas/discovery/SearchIndexer.java
index 8e67e32..b35346e 100755
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchIndexer.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchIndexer.java
@@ -18,11 +18,9 @@
package org.apache.atlas.discovery;
-import org.apache.atlas.listener.TypesChangeListener;
-
/**
* Interface for indexing types.
*/
-public interface SearchIndexer extends TypesChangeListener {
+public interface SearchIndexer {
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/main/java/org/apache/atlas/discovery/graph/DefaultGraphPersistenceStrategy.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/graph/DefaultGraphPersistenceStrategy.java b/repository/src/main/java/org/apache/atlas/discovery/graph/DefaultGraphPersistenceStrategy.java
deleted file mode 100755
index 9b0aa4c..0000000
--- a/repository/src/main/java/org/apache/atlas/discovery/graph/DefaultGraphPersistenceStrategy.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.atlas.discovery.graph;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.RequestContext;
-import org.apache.atlas.groovy.GroovyExpression;
-import org.apache.atlas.query.GraphPersistenceStrategies;
-import org.apache.atlas.query.GraphPersistenceStrategies$class;
-import org.apache.atlas.query.TypeUtils;
-import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.MetadataRepository;
-import org.apache.atlas.repository.RepositoryException;
-import org.apache.atlas.repository.graph.GraphBackedMetadataRepository;
-import org.apache.atlas.repository.graph.GraphHelper;
-import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
-import org.apache.atlas.repository.graphdb.AtlasGraph;
-import org.apache.atlas.repository.graphdb.AtlasVertex;
-import org.apache.atlas.repository.graphdb.GremlinVersion;
-import org.apache.atlas.typesystem.ITypedReferenceableInstance;
-import org.apache.atlas.typesystem.ITypedStruct;
-import org.apache.atlas.typesystem.persistence.Id;
-import org.apache.atlas.typesystem.types.AttributeInfo;
-import org.apache.atlas.typesystem.types.ClassType;
-import org.apache.atlas.typesystem.types.DataTypes;
-import org.apache.atlas.typesystem.types.IDataType;
-import org.apache.atlas.typesystem.types.Multiplicity;
-import org.apache.atlas.typesystem.types.StructType;
-import org.apache.atlas.typesystem.types.TraitType;
-import org.apache.atlas.typesystem.types.TypeSystem;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-
-/**
- * Default implementation of GraphPersistenceStrategy.
- */
-public class DefaultGraphPersistenceStrategy implements GraphPersistenceStrategies {
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultGraphPersistenceStrategy.class);
-
- private final GraphBackedMetadataRepository metadataRepository;
-
- @Inject
- public DefaultGraphPersistenceStrategy(MetadataRepository metadataRepository) {
- this.metadataRepository = (GraphBackedMetadataRepository) metadataRepository;
- }
-
- @Override
- public String typeAttributeName() {
- return metadataRepository.getTypeAttributeName();
- }
-
- @Override
- public String superTypeAttributeName() {
- return metadataRepository.getSuperTypeAttributeName();
- }
-
- @Override
- public String edgeLabel(IDataType<?> dataType, AttributeInfo aInfo) {
- try {
- return metadataRepository.getEdgeLabel(dataType, aInfo);
- } catch (AtlasException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String traitLabel(IDataType<?> dataType, String traitName) {
- return metadataRepository.getTraitLabel(dataType, traitName);
- }
-
- @Override
- public String fieldNameInVertex(IDataType<?> dataType, AttributeInfo aInfo) {
- try {
- return metadataRepository.getFieldNameInVertex(dataType, aInfo);
- } catch (AtlasException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public List<String> traitNames(AtlasVertex AtlasVertex) {
- return GraphHelper.getTraitNames(AtlasVertex);
- }
-
- @Override
- public Id getIdFromVertex(String dataTypeName, AtlasVertex vertex) {
- return GraphHelper.getIdFromVertex(dataTypeName, vertex);
- }
-
- @Override
- public ITypedReferenceableInstance constructClassInstanceId(ClassType classType, Object value) {
- try {
- AtlasVertex classVertex = (AtlasVertex) value;
- ITypedReferenceableInstance classInstance = classType.createInstance(GraphHelper.getIdFromVertex(classVertex),
- new String[0]);
- return classType.convert(classInstance, Multiplicity.OPTIONAL);
- } catch (AtlasException e) {
- LOG.error("error while constructing an instance", e);
- }
- return null;
- }
-
- @Override
- public <U> U constructInstance(IDataType<U> dataType, Object value) {
- try {
- switch (dataType.getTypeCategory()) {
- case PRIMITIVE:
- case ENUM:
- return dataType.convert(value, Multiplicity.OPTIONAL);
- case ARRAY:
- DataTypes.ArrayType arrType = (DataTypes.ArrayType) dataType;
- IDataType<?> elemType = arrType.getElemType();
- ImmutableCollection.Builder result = ImmutableList.builder();
- List list = (List) value;
- for(Object listElement : list) {
- Object collectionEntry = constructCollectionEntry(elemType, listElement);
- if(collectionEntry != null) {
- result.add(collectionEntry);
- }
- }
- return (U)result.build();
- case MAP:
- // todo
- break;
-
- case STRUCT:
- AtlasVertex structVertex = (AtlasVertex) value;
- StructType structType = (StructType) dataType;
- ITypedStruct structInstance = structType.createInstance();
- TypeSystem.IdType idType = TypeSystem.getInstance().getIdType();
-
- if (dataType.getName().equals(idType.getName())) {
- structInstance.set(idType.typeNameAttrName(), GraphHelper.getSingleValuedProperty(structVertex, typeAttributeName(), String.class));
- structInstance.set(idType.idAttrName(), GraphHelper.getSingleValuedProperty(structVertex, idAttributeName(), String.class));
- String stateValue = GraphHelper.getSingleValuedProperty(structVertex, stateAttributeName(), String.class);
- if (stateValue != null) {
- structInstance.set(idType.stateAttrName(), stateValue);
- }
- structInstance.set(idType.versionAttrName(), structVertex.getProperty(versionAttributeName(), Integer.class));
- } else {
- metadataRepository.getGraphToInstanceMapper()
- .mapVertexToInstance(structVertex, structInstance, structType.fieldMapping().fields);
- }
- return dataType.convert(structInstance, Multiplicity.OPTIONAL);
-
- case TRAIT:
- AtlasVertex traitVertex = (AtlasVertex) value;
- TraitType traitType = (TraitType) dataType;
- ITypedStruct traitInstance = traitType.createInstance();
- // todo - this is not right, we should load the Instance associated with this
- // trait. for now just loading the trait struct.
- // metadataRepository.getGraphToInstanceMapper().mapVertexToTraitInstance(
- // traitVertex, dataType.getName(), , traitType, traitInstance);
- metadataRepository.getGraphToInstanceMapper()
- .mapVertexToInstance(traitVertex, traitInstance, traitType.fieldMapping().fields);
- break;
-
- case CLASS:
- AtlasVertex classVertex = (AtlasVertex) value;
- String guid = classVertex.getProperty(Constants.GUID_PROPERTY_KEY, String.class);
- // Check if the instance we need was previously loaded.
- ITypedReferenceableInstance classInstance = RequestContext.get().getInstanceV1(guid);
- if (classInstance == null) {
- classInstance = metadataRepository.getGraphToInstanceMapper().mapGraphToTypedInstance(guid, classVertex);
- }
- return dataType.convert(classInstance, Multiplicity.OPTIONAL);
-
- default:
- throw new UnsupportedOperationException("Load for type " + dataType + "is not supported");
- }
- } catch (AtlasException e) {
- LOG.error("error while constructing an instance", e);
- }
-
- return null;
- }
-
- public <U> U constructCollectionEntry(IDataType<U> elementType, Object value) throws AtlasException {
- switch (elementType.getTypeCategory()) {
- case PRIMITIVE:
- case ENUM:
- return constructInstance(elementType, value);
- //The array values in case of STRUCT, CLASS contain the edgeId if the outgoing edge which links to the STRUCT, CLASS vertex referenced
- case STRUCT:
- case CLASS:
- String edgeId = (String) value;
- return (U) metadataRepository.getGraphToInstanceMapper().getReferredEntity(edgeId, elementType);
- case ARRAY:
- case MAP:
- case TRAIT:
- return null;
- default:
- throw new UnsupportedOperationException("Load for type " + elementType + " in collections is not supported");
- }
- }
-
- @Override
- public String edgeLabel(TypeUtils.FieldInfo fInfo) {
- return fInfo.reverseDataType() == null ? edgeLabel(fInfo.dataType(), fInfo.attrInfo()) :
- edgeLabel(fInfo.reverseDataType(), fInfo.attrInfo());
- }
-
- @Override
- public AtlasEdgeDirection instanceToTraitEdgeDirection() {
- return AtlasEdgeDirection.OUT;
- }
-
- @Override
- public AtlasEdgeDirection traitToInstanceEdgeDirection() {
- return AtlasEdgeDirection.IN;
- }
-
- @Override
- public String idAttributeName() {
- return metadataRepository.getIdAttributeName();
- }
-
- @Override
- public String stateAttributeName() {
- return metadataRepository.getStateAttributeName();
- }
-
- @Override
- public String versionAttributeName() {
- return metadataRepository.getVersionAttributeName();
- }
-
- @Override
- public boolean collectTypeInstancesIntoVar() {
- return GraphPersistenceStrategies$class.collectTypeInstancesIntoVar(this);
- }
-
- @Override
- public boolean filterBySubTypes() {
- return GraphPersistenceStrategies$class.filterBySubTypes(this);
- }
-
- @Override
- public boolean addGraphVertexPrefix(scala.collection.Traversable<GroovyExpression> preStatements) {
- return GraphPersistenceStrategies$class.addGraphVertexPrefix(this, preStatements);
- }
-
- @Override
- public GremlinVersion getSupportedGremlinVersion() {
- return GraphPersistenceStrategies$class.getSupportedGremlinVersion(this);
- }
-
- @Override
- public GroovyExpression generatePersisentToLogicalConversionExpression(GroovyExpression expr, IDataType<?> t) {
- return GraphPersistenceStrategies$class.generatePersisentToLogicalConversionExpression(this,expr, t);
- }
-
- @Override
- public GroovyExpression addInitialQueryCondition(GroovyExpression expr) {
- return GraphPersistenceStrategies$class.addInitialQueryCondition(this, expr);
- }
-
- @Override
- public boolean isPropertyValueConversionNeeded(IDataType<?> t) {
- return GraphPersistenceStrategies$class.isPropertyValueConversionNeeded(this, t);
- }
-
- @Override
- public AtlasGraph getGraph() throws RepositoryException {
- return metadataRepository.getGraph();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java
deleted file mode 100755
index aed8659..0000000
--- a/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.atlas.discovery.graph;
-
-import org.apache.atlas.AtlasClient;
-import org.apache.atlas.annotation.GraphTransaction;
-import org.apache.atlas.discovery.DiscoveryException;
-import org.apache.atlas.discovery.DiscoveryService;
-import org.apache.atlas.exception.AtlasBaseException;
-import org.apache.atlas.query.Expressions;
-import org.apache.atlas.query.GremlinEvaluator;
-import org.apache.atlas.query.GremlinQuery;
-import org.apache.atlas.query.GremlinQueryResult;
-import org.apache.atlas.query.GremlinTranslator;
-import org.apache.atlas.query.QueryParams;
-import org.apache.atlas.query.QueryParser;
-import org.apache.atlas.query.QueryProcessor;
-import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.MetadataRepository;
-import org.apache.atlas.repository.graph.GraphHelper;
-import org.apache.atlas.repository.graphdb.AtlasEdge;
-import org.apache.atlas.repository.graphdb.AtlasGraph;
-import org.apache.atlas.repository.graphdb.AtlasIndexQuery;
-import org.apache.atlas.repository.graphdb.AtlasVertex;
-import org.apache.atlas.util.CompiledQueryCacheKey;
-import org.apache.atlas.util.NoopGremlinQuery;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import scala.util.Either;
-import scala.util.parsing.combinator.Parsers;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Graph backed implementation of Search.
- */
-@Singleton
-@Component
-public class GraphBackedDiscoveryService implements DiscoveryService {
-
- private static final Logger LOG = LoggerFactory.getLogger(GraphBackedDiscoveryService.class);
-
- private final AtlasGraph graph;
- private final DefaultGraphPersistenceStrategy graphPersistenceStrategy;
-
- public final static String SCORE = "score";
- /**
- * Where the vertex' internal gremlin id is stored in the Map produced by extractResult()
- */
- public final static String GREMLIN_ID_KEY = "id";
- /**
- * Where the id of an edge's incoming vertex is stored in the Map produced by extractResult()
- */
- public final static String GREMLIN_INVERTEX_KEY = "inVertex";
- /**
- * Where the id of an edge's outgoing vertex is stored in the Map produced by extractResult()
- */
- public final static String GREMLIN_OUTVERTEX_KEY = "outVertex";
- /**
- * Where an edge's label is stored in the Map produced by extractResult()
- */
- public final static String GREMLIN_LABEL_KEY = "label";
-
- @Inject
- GraphBackedDiscoveryService(MetadataRepository metadataRepository, AtlasGraph atlasGraph)
- throws DiscoveryException {
- this.graph = atlasGraph;
- this.graphPersistenceStrategy = new DefaultGraphPersistenceStrategy(metadataRepository);
- }
-
- //For titan 0.5.4, refer to http://s3.thinkaurelius.com/docs/titan/0.5.4/index-backends.html for indexed query
- //http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query
- // .html#query-string-syntax for query syntax
- @Override
- @GraphTransaction
- public String searchByFullText(String query, QueryParams queryParams) throws DiscoveryException {
- String graphQuery = String.format("v.\"%s\":(%s)", Constants.ENTITY_TEXT_PROPERTY_KEY, query);
- LOG.debug("Full text query: {}", graphQuery);
- Iterator<AtlasIndexQuery.Result<?, ?>> results =graph.indexQuery(Constants.FULLTEXT_INDEX, graphQuery).vertices();
- JSONArray response = new JSONArray();
-
- int index = 0;
- while (results.hasNext() && index < queryParams.offset()) {
- results.next();
- index++;
- }
-
- while (results.hasNext() && response.length() < queryParams.limit()) {
-
- AtlasIndexQuery.Result<?,?> result = results.next();
- AtlasVertex<?,?> vertex = result.getVertex();
-
- JSONObject row = new JSONObject();
- String guid = GraphHelper.getGuid(vertex);
- if (guid != null) { //Filter non-class entities
- try {
- row.put("guid", guid);
- row.put(AtlasClient.TYPENAME, GraphHelper.getTypeName(vertex));
- row.put(SCORE, result.getScore());
- } catch (JSONException e) {
- LOG.error("Unable to create response", e);
- throw new DiscoveryException("Unable to create response");
- }
-
- response.put(row);
- }
- }
- return response.toString();
- }
-
- @Override
- @GraphTransaction
- public String searchByDSL(String dslQuery, QueryParams queryParams) throws DiscoveryException {
- GremlinQueryResult queryResult = evaluate(dslQuery, queryParams);
- return queryResult.toJson();
- }
-
- public GremlinQueryResult evaluate(String dslQuery, QueryParams queryParams) throws DiscoveryException {
- if(LOG.isDebugEnabled()) {
- LOG.debug("Executing dsl query={}", dslQuery);
- }
- try {
- GremlinQuery gremlinQuery = parseAndTranslateDsl(dslQuery, queryParams);
- if(gremlinQuery instanceof NoopGremlinQuery) {
- return new GremlinQueryResult(dslQuery, ((NoopGremlinQuery)gremlinQuery).getDataType(), Collections.emptyList());
- }
-
- return new GremlinEvaluator(gremlinQuery, graphPersistenceStrategy, graph).evaluate();
-
- } catch (Exception e) { // unable to catch ExpressionException
- throw new DiscoveryException("Invalid expression : " + dslQuery, e);
- }
- }
-
- private GremlinQuery parseAndTranslateDsl(String dslQuery, QueryParams queryParams) throws DiscoveryException {
-
- CompiledQueryCacheKey entry = new CompiledQueryCacheKey(dslQuery, queryParams);
- GremlinQuery gremlinQuery = QueryProcessor.compiledQueryCache().get(entry);
- if(gremlinQuery == null) {
- Expressions.Expression validatedExpression = parseQuery(dslQuery, queryParams);
-
- //If the final limit is 0, don't launch the query, return with 0 rows
- if (validatedExpression instanceof Expressions.LimitExpression
- && ((Integer)((Expressions.LimitExpression) validatedExpression).limit().rawValue()) == 0) {
- gremlinQuery = new NoopGremlinQuery(validatedExpression.dataType());
- }
- else {
- gremlinQuery = new GremlinTranslator(validatedExpression, graphPersistenceStrategy).translate();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Query = {}", validatedExpression);
- LOG.debug("Expression Tree = {}", validatedExpression.treeString());
- LOG.debug("Gremlin Query = {}", gremlinQuery.queryStr());
- }
- }
- QueryProcessor.compiledQueryCache().put(entry, gremlinQuery);
- }
- return gremlinQuery;
- }
-
- private Expressions.Expression parseQuery(String dslQuery, QueryParams queryParams) throws DiscoveryException {
- Either<Parsers.NoSuccess, Expressions.Expression> either = QueryParser.apply(dslQuery, queryParams);
- if (either.isRight()) {
- Expressions.Expression expression = either.right().get();
- Expressions.Expression validatedExpression = QueryProcessor.validate(expression);
- return validatedExpression;
- } else {
- throw new DiscoveryException("Invalid expression : " + dslQuery + ". " + either.left());
- }
-
- }
-
- /**
- * Assumes the User is familiar with the persistence structure of the Repository.
- * The given query is run uninterpreted against the underlying Graph Store.
- * The results are returned as a List of Rows. each row is a Map of Key,Value pairs.
- *
- * @param gremlinQuery query in gremlin dsl format
- * @return List of Maps
- * @throws org.apache.atlas.discovery.DiscoveryException
- */
- @Override
- @GraphTransaction
- public List<Map<String, String>> searchByGremlin(String gremlinQuery) throws DiscoveryException {
- LOG.debug("Executing gremlin query={}", gremlinQuery);
- try {
- Object o = graph.executeGremlinScript(gremlinQuery, false);
- return extractResult(o);
- } catch (AtlasBaseException e) {
- throw new DiscoveryException(e);
- }
- }
-
- private List<Map<String, String>> extractResult(final Object o) throws DiscoveryException {
- List<Map<String, String>> result = new ArrayList<>();
- if (o instanceof List) {
- List l = (List) o;
-
- for (Object value : l) {
- Map<String, String> oRow = new HashMap<>();
- if (value instanceof Map) {
- @SuppressWarnings("unchecked") Map<Object, Object> iRow = (Map) value;
- for (Map.Entry e : iRow.entrySet()) {
- Object k = e.getKey();
- Object v = e.getValue();
- oRow.put(k.toString(), v.toString());
- }
- } else if (value instanceof AtlasVertex) {
- AtlasVertex<?,?> vertex = (AtlasVertex<?,?>)value;
- for (String key : vertex.getPropertyKeys()) {
- Object propertyValue = GraphHelper.getProperty(vertex, key);
- if (propertyValue != null) {
- oRow.put(key, propertyValue.toString());
- }
- }
- oRow.put(GREMLIN_ID_KEY, vertex.getId().toString());
-
- } else if (value instanceof String) {
- oRow.put("", value.toString());
- } else if(value instanceof AtlasEdge) {
- AtlasEdge edge = (AtlasEdge) value;
- oRow.put(GREMLIN_ID_KEY, edge.getId().toString());
- oRow.put(GREMLIN_LABEL_KEY, edge.getLabel());
- oRow.put(GREMLIN_INVERTEX_KEY, edge.getInVertex().getId().toString());
- oRow.put(GREMLIN_OUTVERTEX_KEY, edge.getOutVertex().getId().toString());
- for (String propertyKey : edge.getPropertyKeys()) {
- oRow.put(propertyKey, GraphHelper.getProperty(edge, propertyKey).toString());
- }
- } else {
- throw new DiscoveryException(String.format("Cannot process result %s", String.valueOf(value)));
- }
-
- result.add(oRow);
- }
- }
- else {
- result.add(new HashMap<String, String>() {{
- put("result", o.toString());
- }});
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
deleted file mode 100644
index 27de0ed..0000000
--- a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.atlas.gremlin;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.groovy.AbstractFunctionExpression;
-import org.apache.atlas.groovy.CastExpression;
-import org.apache.atlas.groovy.ClosureExpression;
-import org.apache.atlas.groovy.ComparisonExpression;
-import org.apache.atlas.groovy.ComparisonExpression.ComparisonOperator;
-import org.apache.atlas.groovy.ComparisonOperatorExpression;
-import org.apache.atlas.groovy.FieldExpression;
-import org.apache.atlas.groovy.FunctionCallExpression;
-import org.apache.atlas.groovy.GroovyExpression;
-import org.apache.atlas.groovy.IdentifierExpression;
-import org.apache.atlas.groovy.ListExpression;
-import org.apache.atlas.groovy.LiteralExpression;
-import org.apache.atlas.groovy.LogicalExpression;
-import org.apache.atlas.groovy.LogicalExpression.LogicalOperator;
-import org.apache.atlas.groovy.RangeExpression;
-import org.apache.atlas.groovy.TernaryOperatorExpression;
-import org.apache.atlas.groovy.TraversalStepType;
-import org.apache.atlas.query.GraphPersistenceStrategies;
-import org.apache.atlas.query.TypeUtils.FieldInfo;
-import org.apache.atlas.typesystem.types.IDataType;
-
-
-/**
- * Generates gremlin query expressions using Gremlin 2 syntax.
- *
- */
-public class Gremlin2ExpressionFactory extends GremlinExpressionFactory {
-
- private static final String LOOP_METHOD = "loop";
- private static final String CONTAINS = "contains";
- private static final String LOOP_COUNT_FIELD = "loops";
- private static final String PATH_FIELD = "path";
- private static final String ENABLE_PATH_METHOD = "enablePath";
- private static final String BACK_METHOD = "back";
- private static final String LAST_METHOD = "last";
-
- @Override
- public GroovyExpression generateLogicalExpression(GroovyExpression parent, String operator, List<GroovyExpression> operands) {
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, operator, operands);
- }
-
-
- @Override
- public GroovyExpression generateBackReferenceExpression(GroovyExpression parent, boolean inSelect, String alias) {
- if (inSelect && parent == null) {
- return getFieldInSelect();
- }
- else if (inSelect && parent != null) {
- return parent;
- }
- else {
- return new FunctionCallExpression(TraversalStepType.MAP_TO_ELEMENT, parent, BACK_METHOD, new LiteralExpression(alias));
- }
- }
-
- @Override
- public GroovyExpression getLoopExpressionParent(GroovyExpression inputQry) {
- return inputQry;
- }
-
- @Override
- public GroovyExpression generateLoopExpression(GroovyExpression parent,GraphPersistenceStrategies s, IDataType dataType, GroovyExpression loopExpr, String alias, Integer times) {
-
- GroovyExpression emitExpr = generateLoopEmitExpression(s, dataType);
- //note that in Gremlin 2 (unlike Gremlin 3), the parent is not explicitly used. It is incorporated
- //in the loopExpr.
- GroovyExpression whileFunction = null;
- if(times != null) {
- GroovyExpression loopsExpr = new FieldExpression(getItVariable(), LOOP_COUNT_FIELD);
- GroovyExpression timesExpr = new LiteralExpression(times);
- whileFunction = new ClosureExpression(new ComparisonExpression(loopsExpr, ComparisonOperator.LESS_THAN, timesExpr));
- }
- else {
- GroovyExpression pathExpr = new FieldExpression(getItVariable(),PATH_FIELD);
- GroovyExpression itObjectExpr = getCurrentObjectExpression();
- GroovyExpression pathContainsExpr = new FunctionCallExpression(pathExpr, CONTAINS, itObjectExpr);
- whileFunction = new ClosureExpression(new TernaryOperatorExpression(pathContainsExpr, LiteralExpression.FALSE, LiteralExpression.TRUE));
- }
- GroovyExpression emitFunction = new ClosureExpression(emitExpr);
- GroovyExpression loopCall = new FunctionCallExpression(TraversalStepType.BRANCH, loopExpr, LOOP_METHOD, new LiteralExpression(alias), whileFunction, emitFunction);
-
- return new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, loopCall, ENABLE_PATH_METHOD);
- }
-
- @Override
- public GroovyExpression typeTestExpression(GraphPersistenceStrategies s, String typeName, GroovyExpression itRef) {
-
- GroovyExpression superTypeAttrExpr = new FieldExpression(itRef, s.superTypeAttributeName());
- GroovyExpression typeNameExpr = new LiteralExpression(typeName);
- GroovyExpression isSuperTypeExpr = new FunctionCallExpression(superTypeAttrExpr, CONTAINS, typeNameExpr);
- GroovyExpression superTypeMatchesExpr = new TernaryOperatorExpression(superTypeAttrExpr, isSuperTypeExpr, LiteralExpression.FALSE);
-
- GroovyExpression typeAttrExpr = new FieldExpression(itRef, s.typeAttributeName());
- GroovyExpression typeMatchesExpr = new ComparisonExpression(typeAttrExpr, ComparisonOperator.EQUALS, typeNameExpr);
- return new LogicalExpression(typeMatchesExpr, LogicalOperator.OR, superTypeMatchesExpr);
-
- }
-
- @Override
- public GroovyExpression generateSelectExpression(GroovyExpression parent, List<LiteralExpression> sourceNames,
- List<GroovyExpression> srcExprs) {
-
- GroovyExpression srcNamesExpr = new ListExpression(sourceNames);
- List<GroovyExpression> selectArgs = new ArrayList<>();
- selectArgs.add(srcNamesExpr);
- for(GroovyExpression expr : srcExprs) {
- selectArgs.add(new ClosureExpression(expr));
- }
- return new FunctionCallExpression(TraversalStepType.MAP_TO_VALUE, parent, SELECT_METHOD, selectArgs);
- }
-
- @Override
- public GroovyExpression generateFieldExpression(GroovyExpression parent, FieldInfo fInfo, String propertyName, boolean inSelect) {
- return new FieldExpression(parent, propertyName);
- }
-
- @Override
- public GroovyExpression generateHasExpression(GraphPersistenceStrategies s, GroovyExpression parent, String propertyName, String symbol,
- GroovyExpression requiredValue, FieldInfo fInfo) throws AtlasException {
- GroovyExpression op = gremlin2CompOp(symbol);
- GroovyExpression propertyNameExpr = new LiteralExpression(propertyName);
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, HAS_METHOD, propertyNameExpr, op, requiredValue);
- }
-
- @Override
- public GroovyExpression generateLikeExpressionUsingFilter(GroovyExpression parent, String propertyName, GroovyExpression propertyValue) throws AtlasException {
- GroovyExpression itExpr = getItVariable();
- GroovyExpression nameExpr = new FieldExpression(itExpr, propertyName);
- GroovyExpression matchesExpr = new FunctionCallExpression(nameExpr, MATCHES, escapePropertyValue(propertyValue));
- GroovyExpression closureExpr = new ClosureExpression(matchesExpr);
-
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, closureExpr);
- }
-
- private GroovyExpression escapePropertyValue(GroovyExpression propertyValue) {
- GroovyExpression ret = propertyValue;
-
- if (propertyValue instanceof LiteralExpression) {
- LiteralExpression exp = (LiteralExpression) propertyValue;
-
- if (exp != null && exp.getValue() instanceof String) {
- String stringValue = (String) exp.getValue();
-
- // replace '*' with ".*", replace '?' with '.'
- stringValue = stringValue.replaceAll("\\*", ".*")
- .replaceAll("\\?", ".");
-
- ret = new LiteralExpression(stringValue);
- }
- }
-
- return ret;
- }
-
- private GroovyExpression gremlin2CompOp(String op) throws AtlasException {
-
- GroovyExpression tExpr = new IdentifierExpression("T");
- if(op.equals("=")) {
- return new FieldExpression(tExpr, "eq");
- }
- if(op.equals("!=")) {
- return new FieldExpression(tExpr, "neq");
- }
- if(op.equals(">")) {
- return new FieldExpression(tExpr, "gt");
- }
- if(op.equals(">=")) {
- return new FieldExpression(tExpr, "gte");
- }
- if(op.equals("<")) {
- return new FieldExpression(tExpr, "lt");
- }
- if(op.equals("<=")) {
- return new FieldExpression(tExpr, "lte");
- }
- if(op.equals("in")) {
- return new FieldExpression(tExpr, "in");
- }
- throw new AtlasException("Comparison operator " + op + " not supported in Gremlin");
- }
-
- @Override
- protected GroovyExpression initialExpression(GroovyExpression varExpr, GraphPersistenceStrategies s) {
- return generateSeededTraversalExpresssion(false, varExpr);
- }
-
- @Override
- public GroovyExpression generateSeededTraversalExpresssion(boolean isMap, GroovyExpression varExpr) {
- return new FunctionCallExpression(TraversalStepType.START, varExpr, "_");
- }
-
- @Override
- public GroovyExpression generateRangeExpression(GroovyExpression parent, int startIndex, int endIndex) {
- //treat as barrier step, since limits need to be applied globally (even though it
- //is technically a filter step)
- return new RangeExpression(TraversalStepType.BARRIER, parent, startIndex, endIndex);
- }
-
- @Override
- public boolean isRangeExpression(GroovyExpression expr) {
-
- return (expr instanceof RangeExpression);
- }
-
- @Override
- public int[] getRangeParameters(AbstractFunctionExpression expr) {
-
- if (isRangeExpression(expr)) {
- RangeExpression rangeExpression = (RangeExpression) expr;
- return new int[] {rangeExpression.getStartIndex(), rangeExpression.getEndIndex()};
- }
- else {
- return null;
- }
- }
-
- @Override
- public void setRangeParameters(GroovyExpression expr, int startIndex, int endIndex) {
-
- if (isRangeExpression(expr)) {
- RangeExpression rangeExpression = (RangeExpression) expr;
- rangeExpression.setStartIndex(startIndex);
- rangeExpression.setEndIndex(endIndex);
- }
- else {
- throw new IllegalArgumentException(expr.getClass().getName() + " is not a valid range expression - must be an instance of " + RangeExpression.class.getName());
- }
-
- }
-
- @Override
- public List<GroovyExpression> getOrderFieldParents() {
-
- GroovyExpression itExpr = getItVariable();
- List<GroovyExpression> result = new ArrayList<>(2);
- result.add(new FieldExpression(itExpr, "a"));
- result.add(new FieldExpression(itExpr, "b"));
- return result;
- }
-
-
- @Override
- public GroovyExpression generateOrderByExpression(GroovyExpression parent, List<GroovyExpression> translatedOrderBy, boolean isAscending) {
-
- GroovyExpression aPropertyExpr = translatedOrderBy.get(0);
- GroovyExpression bPropertyExpr = translatedOrderBy.get(1);
-
- GroovyExpression aPropertyNotNull = new ComparisonExpression(aPropertyExpr, ComparisonOperator.NOT_EQUALS, LiteralExpression.NULL);
- GroovyExpression bPropertyNotNull = new ComparisonExpression(bPropertyExpr, ComparisonOperator.NOT_EQUALS, LiteralExpression.NULL);
-
- GroovyExpression aCondition = new TernaryOperatorExpression(aPropertyNotNull, new FunctionCallExpression(aPropertyExpr,TO_LOWER_CASE_METHOD), aPropertyExpr);
- GroovyExpression bCondition = new TernaryOperatorExpression(bPropertyNotNull, new FunctionCallExpression(bPropertyExpr,TO_LOWER_CASE_METHOD), bPropertyExpr);
-
- GroovyExpression comparisonFunction = null;
- if(isAscending) {
- comparisonFunction = new ComparisonOperatorExpression(aCondition, bCondition);
- }
- else {
- comparisonFunction = new ComparisonOperatorExpression(bCondition, aCondition);
- }
- return new FunctionCallExpression(TraversalStepType.BARRIER, parent, ORDER_METHOD, new ClosureExpression(comparisonFunction));
- }
-
-
- @Override
- public GroovyExpression getAnonymousTraversalExpression() {
- return new FunctionCallExpression(TraversalStepType.START, "_");
- }
-
-
-
- @Override
- public GroovyExpression generateGroupByExpression(GroovyExpression parent, GroovyExpression groupByExpression,
- GroovyExpression aggregationFunction) {
- GroovyExpression groupByClosureExpr = new ClosureExpression(groupByExpression);
- GroovyExpression itClosure = new ClosureExpression(getItVariable());
- GroovyExpression result = new FunctionCallExpression(TraversalStepType.BARRIER, parent, "groupBy", groupByClosureExpr, itClosure);
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, "cap");
- result = new FunctionCallExpression(TraversalStepType.END, result, "next");
- result = new FunctionCallExpression(result, "values");
- result = new FunctionCallExpression(result, "toList");
-
- GroovyExpression aggregrationFunctionClosure = new ClosureExpression(aggregationFunction);
- result = new FunctionCallExpression(result, "collect", aggregrationFunctionClosure);
- return result;
- }
-
- @Override
- public GroovyExpression getFieldInSelect() {
- return getItVariable();
- }
- @Override
- public GroovyExpression getGroupBySelectFieldParent() {
- GroovyExpression itExpr = getItVariable();
- return new FunctionCallExpression(itExpr, LAST_METHOD);
- }
-
- //assumes cast already performed
- @Override
- public GroovyExpression generateCountExpression(GroovyExpression itExpr) {
- return new FunctionCallExpression(itExpr, "size");
- }
-
- @Override
- public String getTraversalExpressionClass() {
- return "GremlinPipeline";
- }
-
-
- @Override
- public boolean isSelectGeneratesMap(int aliasCount) {
- //in Gremlin 2 select always generates a map
- return true;
- }
-
- @Override
- public GroovyExpression generateMapExpression(GroovyExpression parent, ClosureExpression closureExpression) {
- return new FunctionCallExpression(TraversalStepType.MAP_TO_ELEMENT, parent, "transform", closureExpression);
- }
-
- @Override
- public GroovyExpression generateGetSelectedValueExpression(LiteralExpression key,
- GroovyExpression rowMap) {
- rowMap = new CastExpression(rowMap, "Row");
- GroovyExpression getExpr = new FunctionCallExpression(rowMap, "getColumn", key);
- return getExpr;
- }
-
- @Override
- public GroovyExpression getCurrentTraverserObject(GroovyExpression traverser) {
- return traverser;
- }
-
- public List<String> getAliasesRequiredByExpression(GroovyExpression expr) {
- if(!(expr instanceof FunctionCallExpression)) {
- return Collections.emptyList();
- }
- FunctionCallExpression fc = (FunctionCallExpression)expr;
- if(! fc.getFunctionName().equals(LOOP_METHOD)) {
- return Collections.emptyList();
- }
- LiteralExpression aliasName = (LiteralExpression)fc.getArguments().get(0);
- return Collections.singletonList(aliasName.getValue().toString());
- }
-
- @Override
- public boolean isRepeatExpression(GroovyExpression expr) {
- if(!(expr instanceof FunctionCallExpression)) {
- return false;
- }
- return ((FunctionCallExpression)expr).getFunctionName().equals(LOOP_METHOD);
- }
-}
-
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
deleted file mode 100644
index b936695..0000000
--- a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.atlas.gremlin;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.groovy.AbstractFunctionExpression;
-import org.apache.atlas.groovy.CastExpression;
-import org.apache.atlas.groovy.ClosureExpression;
-import org.apache.atlas.groovy.ComparisonExpression;
-import org.apache.atlas.groovy.ComparisonExpression.ComparisonOperator;
-import org.apache.atlas.groovy.ComparisonOperatorExpression;
-import org.apache.atlas.groovy.FieldExpression;
-import org.apache.atlas.groovy.FunctionCallExpression;
-import org.apache.atlas.groovy.GroovyExpression;
-import org.apache.atlas.groovy.IdentifierExpression;
-import org.apache.atlas.groovy.LiteralExpression;
-import org.apache.atlas.groovy.LogicalExpression;
-import org.apache.atlas.groovy.LogicalExpression.LogicalOperator;
-import org.apache.atlas.groovy.TernaryOperatorExpression;
-import org.apache.atlas.groovy.TraversalStepType;
-import org.apache.atlas.groovy.TypeCoersionExpression;
-import org.apache.atlas.query.GraphPersistenceStrategies;
-import org.apache.atlas.query.TypeUtils.FieldInfo;
-import org.apache.atlas.repository.graph.AtlasGraphProvider;
-import org.apache.atlas.repository.graphdb.AtlasGraph;
-import org.apache.atlas.typesystem.types.AttributeInfo;
-import org.apache.atlas.typesystem.types.IDataType;
-
-/**
- * Generates gremlin query expressions using Gremlin 3 syntax.
- *
- */
-public class Gremlin3ExpressionFactory extends GremlinExpressionFactory {
-
-
-
- private static final String VERTEX_LIST_CLASS = "List<Vertex>";
- private static final String VERTEX_ARRAY_CLASS = "Vertex[]";
- private static final String OBJECT_ARRAY_CLASS = "Object[]";
- private static final String VERTEX_CLASS = "Vertex";
- private static final String FUNCTION_CLASS = "Function";
-
- private static final String VALUE_METHOD = "value";
- private static final String IS_PRESENT_METHOD = "isPresent";
- private static final String MAP_METHOD = "map";
- private static final String VALUES_METHOD = "values";
- private static final String GET_METHOD = "get";
- private static final String OR_ELSE_METHOD = "orElse";
- private static final String PROPERTY_METHOD = "property";
- private static final String BY_METHOD = "by";
- private static final String EQ_METHOD = "eq";
- private static final String EMIT_METHOD = "emit";
- private static final String TIMES_METHOD = "times";
- private static final String REPEAT_METHOD = "repeat";
- private static final String RANGE_METHOD = "range";
- private static final String LAST_METHOD = "last";
- private static final String TO_STRING_METHOD = "toString";
-
- private static final GroovyExpression EMPTY_STRING_EXPRESSION = new LiteralExpression("");
-
- @Override
- public GroovyExpression generateLogicalExpression(GroovyExpression parent, String operator,
- List<GroovyExpression> operands) {
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, operator, operands);
- }
-
- @Override
- public GroovyExpression generateBackReferenceExpression(GroovyExpression parent, boolean inSelect, String alias) {
- if (inSelect) {
- return getFieldInSelect();
- } else {
- return new FunctionCallExpression(TraversalStepType.MAP_TO_ELEMENT, parent, SELECT_METHOD, new LiteralExpression(alias));
- }
- }
-
- @Override
- public GroovyExpression typeTestExpression(GraphPersistenceStrategies s, String typeName, GroovyExpression itRef) {
- LiteralExpression superTypeAttrExpr = new LiteralExpression(s.superTypeAttributeName());
- LiteralExpression typeNameExpr = new LiteralExpression(typeName);
- LiteralExpression typeAttrExpr = new LiteralExpression(s.typeAttributeName());
- FunctionCallExpression result = new FunctionCallExpression(TraversalStepType.FILTER, HAS_METHOD, typeAttrExpr, new FunctionCallExpression(EQ_METHOD, typeNameExpr));
- result = new FunctionCallExpression(TraversalStepType.FILTER, result, "or");
- result = new FunctionCallExpression(TraversalStepType.FILTER, result, HAS_METHOD, superTypeAttrExpr, new FunctionCallExpression(EQ_METHOD, typeNameExpr));
- return result;
-
- }
-
- @Override
- public GroovyExpression generateLoopExpression(GroovyExpression parent,GraphPersistenceStrategies s, IDataType dataType, GroovyExpression loopExpr, String alias, Integer times) {
-
- GroovyExpression emitExpr = generateLoopEmitExpression(s, dataType);
-
- GroovyExpression result = new FunctionCallExpression(TraversalStepType.BRANCH, parent, REPEAT_METHOD, loopExpr);
- if (times != null) {
- GroovyExpression timesExpr = new LiteralExpression(times);
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, TIMES_METHOD, timesExpr);
- }
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, EMIT_METHOD, emitExpr);
- return result;
-
- }
-
- @Override
- public GroovyExpression getLoopExpressionParent(GroovyExpression inputQry) {
- GroovyExpression curTraversal = getAnonymousTraversalStartExpression();
- return curTraversal;
- }
-
- private IdentifierExpression getAnonymousTraversalStartExpression() {
- return new IdentifierExpression(TraversalStepType.START, "__");
- }
-
- @Override
- public GroovyExpression generateSelectExpression(GroovyExpression parent, List<LiteralExpression> sourceNames,
- List<GroovyExpression> srcExprs) {
- FunctionCallExpression result = new FunctionCallExpression(TraversalStepType.MAP_TO_VALUE, parent, SELECT_METHOD, sourceNames);
-
- for (GroovyExpression expr : srcExprs) {
- GroovyExpression closure = new ClosureExpression(expr);
- GroovyExpression castClosure = new TypeCoersionExpression(closure, FUNCTION_CLASS);
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, BY_METHOD, castClosure);
- }
- return result;
- }
-
- @Override
- public GroovyExpression generateFieldExpression(GroovyExpression parent, FieldInfo fInfo,
- String propertyName, boolean inSelect) {
-
- AttributeInfo attrInfo = fInfo.attrInfo();
- IDataType attrType = attrInfo.dataType();
- GroovyExpression propertyNameExpr = new LiteralExpression(propertyName);
- //Whether it is the user or shared graph does not matter here, since we're
- //just getting the conversion expression. Ideally that would be moved someplace else.
- AtlasGraph graph = AtlasGraphProvider.getGraphInstance();
- if (inSelect) {
-
- GroovyExpression expr = new FunctionCallExpression(parent, PROPERTY_METHOD, propertyNameExpr);
- expr = new FunctionCallExpression(expr, OR_ELSE_METHOD, LiteralExpression.NULL);
- return graph.generatePersisentToLogicalConversionExpression(expr, attrType);
- } else {
-
- GroovyExpression unmapped = new FunctionCallExpression(TraversalStepType.FLAT_MAP_TO_VALUES, parent, VALUES_METHOD, propertyNameExpr);
- if (graph.isPropertyValueConversionNeeded(attrType)) {
- GroovyExpression toConvert = new FunctionCallExpression(getItVariable(), GET_METHOD);
-
- GroovyExpression conversionFunction = graph.generatePersisentToLogicalConversionExpression(toConvert,
- attrType);
- return new FunctionCallExpression(TraversalStepType.MAP_TO_VALUE, unmapped, MAP_METHOD, new ClosureExpression(conversionFunction));
- } else {
- return unmapped;
- }
-
- }
- }
-
- private ComparisonOperator getGroovyOperator(String symbol) throws AtlasException {
-
- String toFind = symbol;
- if (toFind.equals("=")) {
- toFind = "==";
- }
- return ComparisonOperator.lookup(toFind);
- }
-
- private String getComparisonFunction(String op) throws AtlasException {
-
- if (op.equals("=")) {
- return "eq";
- }
- if (op.equals("!=")) {
- return "neq";
- }
- if (op.equals(">")) {
- return "gt";
- }
- if (op.equals(">=")) {
- return "gte";
- }
- if (op.equals("<")) {
- return "lt";
- }
- if (op.equals("<=")) {
- return "lte";
- }
- throw new AtlasException("Comparison operator " + op + " not supported in Gremlin");
- }
-
- @Override
- public GroovyExpression generateHasExpression(GraphPersistenceStrategies s, GroovyExpression parent,
- String propertyName, String symbol, GroovyExpression requiredValue, FieldInfo fInfo) throws AtlasException {
-
- AttributeInfo attrInfo = fInfo.attrInfo();
- IDataType attrType = attrInfo.dataType();
- GroovyExpression propertNameExpr = new LiteralExpression(propertyName);
- if (s.isPropertyValueConversionNeeded(attrType)) {
- // for some types, the logical value cannot be stored directly in
- // the underlying graph,
- // and conversion logic is needed to convert the persistent form of
- // the value
- // to the actual value. In cases like this, we generate a conversion
- // expression to
- // do this conversion and use the filter step to perform the
- // comparsion in the gremlin query
- GroovyExpression itExpr = getItVariable();
- GroovyExpression vertexExpr = new CastExpression(new FunctionCallExpression(itExpr, GET_METHOD), VERTEX_CLASS);
- GroovyExpression propertyValueExpr = new FunctionCallExpression(vertexExpr, VALUE_METHOD, propertNameExpr);
- GroovyExpression conversionExpr = s.generatePersisentToLogicalConversionExpression(propertyValueExpr,
- attrType);
-
- GroovyExpression propertyIsPresentExpression = new FunctionCallExpression(
- new FunctionCallExpression(vertexExpr, PROPERTY_METHOD, propertNameExpr), IS_PRESENT_METHOD);
- GroovyExpression valueMatchesExpr = new ComparisonExpression(conversionExpr, getGroovyOperator(symbol),
- requiredValue);
-
- GroovyExpression filterCondition = new LogicalExpression(propertyIsPresentExpression, LogicalOperator.AND,
- valueMatchesExpr);
-
- GroovyExpression filterFunction = new ClosureExpression(filterCondition);
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, filterFunction);
- } else {
- GroovyExpression valueMatches = new FunctionCallExpression(getComparisonFunction(symbol), requiredValue);
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, HAS_METHOD, propertNameExpr, valueMatches);
- }
- }
-
- @Override
- public GroovyExpression generateLikeExpressionUsingFilter(GroovyExpression parent, String propertyName, GroovyExpression propertyValue) throws AtlasException {
- GroovyExpression vertexExpr = new FunctionCallExpression(getItVariable(), GET_METHOD);
- GroovyExpression propertyValueExpr = new FunctionCallExpression(vertexExpr, VALUE_METHOD, new LiteralExpression(propertyName));
- GroovyExpression matchesExpr = new FunctionCallExpression(propertyValueExpr, MATCHES, escapePropertyValue(propertyValue));
- GroovyExpression closureExpr = new ClosureExpression(matchesExpr);
-
- return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, closureExpr);
- }
-
- private GroovyExpression escapePropertyValue(GroovyExpression propertyValue) {
- GroovyExpression ret = propertyValue;
-
- if (propertyValue instanceof LiteralExpression) {
- LiteralExpression exp = (LiteralExpression) propertyValue;
-
- if (exp != null && exp.getValue() instanceof String) {
- String stringValue = (String) exp.getValue();
-
- // replace '*' with ".*", replace '?' with '.'
- stringValue = stringValue.replaceAll("\\*", ".*")
- .replaceAll("\\?", ".");
-
- ret = new LiteralExpression(stringValue);
- }
- }
-
- return ret;
- }
-
- @Override
- protected GroovyExpression initialExpression(GroovyExpression varExpr, GraphPersistenceStrategies s) {
-
- // this bit of groovy magic converts the set of vertices in varName into
- // a String containing the ids of all the vertices. This becomes the
- // argument
- // to g.V(). This is needed because Gremlin 3 does not support
- // _()
- // s"g.V(${varName}.collect{it.id()} as String[])"
-
- GroovyExpression gExpr = getGraphExpression();
- GroovyExpression varRefExpr = new TypeCoersionExpression(varExpr, OBJECT_ARRAY_CLASS);
- GroovyExpression matchingVerticesExpr = new FunctionCallExpression(TraversalStepType.START, gExpr, V_METHOD, varRefExpr);
- GroovyExpression isEmpty = new FunctionCallExpression(varExpr, "isEmpty");
- GroovyExpression emptyGraph = getEmptyTraversalExpression();
-
- GroovyExpression expr = new TernaryOperatorExpression(isEmpty, emptyGraph, matchingVerticesExpr);
-
- return s.addInitialQueryCondition(expr);
- }
-
- private GroovyExpression getEmptyTraversalExpression() {
- GroovyExpression emptyGraph = new FunctionCallExpression(TraversalStepType.START, getGraphExpression(), V_METHOD, EMPTY_STRING_EXPRESSION);
- return emptyGraph;
- }
-
- @Override
- public GroovyExpression generateRangeExpression(GroovyExpression parent, int startIndex, int endIndex) {
- //treat as barrier step, since limits need to be applied globally (even though it
- //is technically a filter step)
- return new FunctionCallExpression(TraversalStepType.BARRIER, parent, RANGE_METHOD, new LiteralExpression(startIndex), new LiteralExpression(endIndex));
- }
-
- @Override
- public boolean isRangeExpression(GroovyExpression expr) {
-
- return (expr instanceof FunctionCallExpression && ((FunctionCallExpression)expr).getFunctionName().equals(RANGE_METHOD));
- }
-
- @Override
- public int[] getRangeParameters(AbstractFunctionExpression expr) {
-
- if (isRangeExpression(expr)) {
- FunctionCallExpression rangeExpression = (FunctionCallExpression) expr;
- List<GroovyExpression> arguments = rangeExpression.getArguments();
- int startIndex = (int)((LiteralExpression)arguments.get(0)).getValue();
- int endIndex = (int)((LiteralExpression)arguments.get(1)).getValue();
- return new int[]{startIndex, endIndex};
- }
- else {
- return null;
- }
- }
-
- @Override
- public void setRangeParameters(GroovyExpression expr, int startIndex, int endIndex) {
-
- if (isRangeExpression(expr)) {
- FunctionCallExpression rangeExpression = (FunctionCallExpression) expr;
- rangeExpression.setArgument(0, new LiteralExpression(Integer.valueOf(startIndex)));
- rangeExpression.setArgument(1, new LiteralExpression(Integer.valueOf(endIndex)));
- }
- else {
- throw new IllegalArgumentException(expr + " is not a valid range expression");
- }
- }
-
- @Override
- public List<GroovyExpression> getOrderFieldParents() {
-
- List<GroovyExpression> result = new ArrayList<>(1);
- result.add(null);
- return result;
- }
-
- @Override
- public GroovyExpression generateOrderByExpression(GroovyExpression parent, List<GroovyExpression> translatedOrderBy,
- boolean isAscending) {
-
- GroovyExpression orderByExpr = translatedOrderBy.get(0);
- GroovyExpression orderByClosure = new ClosureExpression(orderByExpr);
- GroovyExpression orderByClause = new TypeCoersionExpression(orderByClosure, FUNCTION_CLASS);
-
- GroovyExpression aExpr = new IdentifierExpression("a");
- GroovyExpression bExpr = new IdentifierExpression("b");
-
- GroovyExpression aCompExpr = new FunctionCallExpression(new FunctionCallExpression(aExpr, TO_STRING_METHOD), TO_LOWER_CASE_METHOD);
- GroovyExpression bCompExpr = new FunctionCallExpression(new FunctionCallExpression(bExpr, TO_STRING_METHOD), TO_LOWER_CASE_METHOD);
-
- GroovyExpression comparisonExpr = null;
- if (isAscending) {
- comparisonExpr = new ComparisonOperatorExpression(aCompExpr, bCompExpr);
- } else {
- comparisonExpr = new ComparisonOperatorExpression(bCompExpr, aCompExpr);
- }
- ClosureExpression comparisonFunction = new ClosureExpression(comparisonExpr, "a", "b");
- FunctionCallExpression orderCall = new FunctionCallExpression(TraversalStepType.BARRIER, parent, ORDER_METHOD);
- return new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, orderCall, BY_METHOD, orderByClause, comparisonFunction);
- }
-
- @Override
- public GroovyExpression getAnonymousTraversalExpression() {
- return null;
- }
-
- @Override
- public GroovyExpression getFieldInSelect() {
- // this logic is needed to remove extra results from
- // what is emitted by repeat loops. Technically
- // for queries that don't have a loop in them we could just use "it"
- // the reason for this is that in repeat loops with an alias,
- // although the alias gets set to the right value, for some
- // reason the select actually includes all vertices that were traversed
- // through in the loop. In these cases, we only want the last vertex
- // traversed in the loop to be selected. The logic here handles that
- // case by converting the result to a list and just selecting the
- // last item from it.
-
- GroovyExpression itExpr = getItVariable();
- GroovyExpression expr1 = new TypeCoersionExpression(itExpr, VERTEX_ARRAY_CLASS);
- GroovyExpression expr2 = new TypeCoersionExpression(expr1, VERTEX_LIST_CLASS);
-
- return new FunctionCallExpression(expr2, LAST_METHOD);
- }
-
- @Override
- public GroovyExpression generateGroupByExpression(GroovyExpression parent, GroovyExpression groupByExpression,
- GroovyExpression aggregationFunction) {
-
- GroovyExpression result = new FunctionCallExpression(TraversalStepType.BARRIER, parent, "group");
- GroovyExpression groupByClosureExpr = new TypeCoersionExpression(new ClosureExpression(groupByExpression), "Function");
- result = new FunctionCallExpression(TraversalStepType.SIDE_EFFECT, result, "by", groupByClosureExpr);
- result = new FunctionCallExpression(TraversalStepType.END, result, "toList");
-
- GroovyExpression mapValuesClosure = new ClosureExpression(new FunctionCallExpression(new CastExpression(getItVariable(), "Map"), "values"));
-
- result = new FunctionCallExpression(result, "collect", mapValuesClosure);
-
- //when we call Map.values(), we end up with an extra list around the result. We remove this by calling toList().get(0). This
- //leaves us with a list of lists containing the vertices that match each group. We then apply the aggregation functions
- //specified in the select list to each of these inner lists.
-
- result = new FunctionCallExpression(result ,"toList");
- result = new FunctionCallExpression(result, "get", new LiteralExpression(0));
-
- GroovyExpression aggregrationFunctionClosure = new ClosureExpression(aggregationFunction);
- result = new FunctionCallExpression(result, "collect", aggregrationFunctionClosure);
- return result;
- }
-
- @Override
- public GroovyExpression generateSeededTraversalExpresssion(boolean isMap, GroovyExpression valueCollection) {
- GroovyExpression coersedExpression = new TypeCoersionExpression(valueCollection, isMap ? "Map[]" : "Vertex[]");
- if(isMap) {
-
- return new FunctionCallExpression(TraversalStepType.START, "__", coersedExpression);
- }
- else {
- //We cannot always use an anonymous traversal because that breaks repeat steps
- return new FunctionCallExpression(TraversalStepType.START, getEmptyTraversalExpression(), "inject", coersedExpression);
- }
- }
-
- @Override
- public GroovyExpression getGroupBySelectFieldParent() {
- return null;
- }
-
- @Override
- public String getTraversalExpressionClass() {
- return "GraphTraversal";
- }
-
- @Override
- public boolean isSelectGeneratesMap(int aliasCount) {
- //in Gremlin 3, you only get a map if there is more than 1 alias.
- return aliasCount > 1;
- }
-
- @Override
- public GroovyExpression generateMapExpression(GroovyExpression parent, ClosureExpression closureExpression) {
- return new FunctionCallExpression(TraversalStepType.MAP_TO_ELEMENT, parent, "map", closureExpression);
- }
-
- @Override
- public GroovyExpression generateGetSelectedValueExpression(LiteralExpression key,
- GroovyExpression rowMapExpr) {
- rowMapExpr = new CastExpression(rowMapExpr, "Map");
- GroovyExpression getExpr = new FunctionCallExpression(rowMapExpr, "get", key);
- return getExpr;
- }
-
- @Override
- public GroovyExpression getCurrentTraverserObject(GroovyExpression traverser) {
- return new FunctionCallExpression(traverser, "get");
- }
-
- public List<String> getAliasesRequiredByExpression(GroovyExpression expr) {
- return Collections.emptyList();
- }
-
- @Override
- public boolean isRepeatExpression(GroovyExpression expr) {
- if(!(expr instanceof FunctionCallExpression)) {
- return false;
- }
- return ((FunctionCallExpression)expr).getFunctionName().equals(REPEAT_METHOD);
- }
-}