
org.neo4j.cypher.internal.helpers.CollectionSupport.scala Maven / Gradle / Ivy
/**
* Copyright (c) 2002-2015 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.cypher.internal.helpers
import collection.Seq
import collection.Map
import java.lang.{Iterable => JavaIterable}
import java.util.{Map => JavaMap}
import collection.JavaConverters._
object IsCollection extends CollectionSupport {
def unapply(x: Any):Option[Iterable[Any]] = {
val collection = isCollection(x)
if (collection) {
Some(makeTraversable(x))
} else {
None
}
}
}
trait CollectionSupport {
def singleOr[T](in:Iterator[T], or: => Exception):Iterator[T] = new Iterator[T] {
var used = false
def hasNext: Boolean = in.hasNext
def next(): T = {
if(used) {
throw or
}
used = true
in.next()
}
}
class NoValidValuesExceptions extends Exception
def isCollection(x: Any) = castToIterable.isDefinedAt(x)
def liftAsCollection[T](test: PartialFunction[Any, T])(input: Any): Option[Iterable[T]] = try {
input match {
case single if test.isDefinedAt(single) => Some(Seq(test(single)))
case IsCollection(coll) =>
val mappedCollection = coll map {
case elem if test.isDefinedAt(elem) => test(elem)
case _ => throw new NoValidValuesExceptions
}
Some(mappedCollection)
case _ => None
}
} catch {
case _: NoValidValuesExceptions => None
}
def asCollectionOf[T](test: PartialFunction[Any, T])(input: Iterable[Any]): Option[Iterable[T]] =
Some(input map { (elem: Any) => if (test.isDefinedAt(elem)) test(elem) else return None })
def makeTraversable(z: Any): Iterable[Any] = if (castToIterable.isDefinedAt(z)) {
castToIterable(z)
} else {
if (z == null) Iterable() else Iterable(z)
}
protected def castToIterable: PartialFunction[Any, Iterable[Any]] = {
case x: Array[_] => x
case x: Map[_, _] => Iterable(x)
case x: JavaMap[_, _] => Iterable(x.asScala)
case x: Traversable[_] => x.toIterable
case x: JavaIterable[_] => x.asScala.map {
case y: JavaMap[_, _] => y.asScala
case y => y
}
}
implicit class RichSeq[T](inner: Seq[T]) {
def foldMap[A](acc: A)(f: (A, T) => (A, T)): (A, Seq[T]) = {
val builder = Seq.newBuilder[T]
var current = acc
for (element <- inner) {
val (newAcc, newElement) = f(current, element)
current = newAcc
builder += newElement
}
(current, builder.result())
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy