blob: ab693b9e299a2b4601172197d3b202bf06009b3f [file] [log] [blame]
/*
* 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.tinkerpop.gremlin.process.traversal.util;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.util.Collection;
import java.util.Set;
/**
* List functions are a separate paradigm for Steps as they behave in a Scope.Local manner by default. This class
* provides helper methods that are common amongst these steps and should be used to keep behavior consistent in terms
* of handling of incoming traversers and argument types.
*/
public interface ListFunction {
/**
* Turn an iterable type into a collection. Doesn't wrap any non-iterable type into an iterable (e.g. single Object
* into list), but will transform one iterable type to another (e.g. array to list).
*
* @param iterable an Iterable or array.
* @return The iterable type as a Collection or null if argument isn't iterable.
*/
public static Collection asCollection(Object iterable) {
if (iterable instanceof Collection) {
return (Collection) iterable;
} else if ((iterable != null && iterable.getClass().isArray()) || iterable instanceof Iterable) {
return (Collection) IteratorUtils.asList(iterable);
} else {
return null;
}
}
/**
* Turn an iterable type into a set. Doesn't wrap any non-iterable type into an iterable (e.g. single Object
* into set), but will transform one iterable type to another (e.g. array to set).
*
* @param iterable an Iterable or array.
* @return The iterable type as a Collection or null if argument isn't iterable.
*/
public static Set asSet(Object iterable) {
if (iterable instanceof Iterable || iterable != null && iterable.getClass().isArray()) {
return IteratorUtils.asSet(iterable);
} else {
return null;
}
}
/**
* Template method used for retrieving the implementing Step's name.
*
* @return this step's name.
*/
public String getStepName();
public default Collection convertArgumentToCollection(Object arg) {
if (null == arg) {
throw new IllegalArgumentException(
String.format("Argument provided for %s step can't be null.", getStepName()));
}
final Collection incoming = asCollection(arg);
if (null == incoming) {
throw new IllegalArgumentException(
String.format(
"%s step can only take an array or an Iterable as an argument, encountered %s",
getStepName(),
arg.getClass()));
}
return incoming;
}
public default <S> Collection convertTraverserToCollection(Traverser.Admin<S> traverser) {
final S items = traverser.get();
if (null == items) {
throw new IllegalArgumentException(
String.format("Incoming traverser for %s step can't be null.", getStepName()));
}
final Collection incoming = asCollection(items);
if (null == incoming) {
throw new IllegalArgumentException(
String.format(
"%s step can only take an array or an Iterable type for incoming traversers, encountered %s",
getStepName(),
items.getClass()));
}
return incoming;
}
public default <S, E> Collection convertTraversalToCollection(Traverser.Admin<S> traverser, final Traversal.Admin<S, E> traversal) {
final Object array = TraversalUtil.apply(traverser, traversal);
if (null == array) {
throw new IllegalArgumentException(
String.format(
"Provided traversal argument for %s step must yield an iterable type, not null",
getStepName()));
}
final Collection input = asCollection(array);
if (null == input) {
throw new IllegalArgumentException(
String.format(
"Provided traversal argument for %s step must yield an iterable type, encountered %s",
getStepName(),
array.getClass()));
}
return input;
}
public default Set convertArgumentToSet(Object arg) {
if (null == arg) {
throw new IllegalArgumentException(
String.format("Argument provided for %s step can't be null.", getStepName()));
}
final Set incoming = asSet(arg);
if (null == incoming) {
throw new IllegalArgumentException(
String.format(
"%s step can only take an array or an Iterable as an argument, encountered %s",
getStepName(),
arg.getClass()));
}
return incoming;
}
public default <S> Set convertTraverserToSet(Traverser.Admin<S> traverser) {
final S items = traverser.get();
if (null == items) {
throw new IllegalArgumentException(
String.format("Incoming traverser for %s step can't be null.", getStepName()));
}
final Set incoming = asSet(items);
if (null == incoming) {
throw new IllegalArgumentException(
String.format(
"%s step can only take an array or an Iterable type for incoming traversers, encountered %s",
getStepName(),
items.getClass()));
}
return incoming;
}
public default <S, E> Set convertTraversalToSet(Traverser.Admin<S> traverser, final Traversal.Admin<S, E> traversal) {
final Object array = TraversalUtil.apply(traverser, traversal);
if (null == array) {
throw new IllegalArgumentException(
String.format(
"Provided traversal argument for %s step must yield an iterable type, not null",
getStepName()));
}
final Set input = asSet(array);
if (null == input) {
throw new IllegalArgumentException(
String.format(
"Provided traversal argument for %s step must yield an iterable type, encountered %s",
getStepName(),
array.getClass()));
}
return input;
}
}