| /* |
| * Copyright (c) 2010, Rickard Öberg. All Rights Reserved. |
| * |
| * 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.qi4j.functional; |
| |
| /** |
| * Common generic specification expressions |
| */ |
| public class Specifications |
| { |
| public static <T> Specification<T> TRUE() |
| { |
| return new Specification<T>() |
| { |
| @Override |
| public boolean satisfiedBy( T instance ) |
| { |
| return true; |
| } |
| }; |
| } |
| |
| public static <T> Specification<T> not( final Specification<T> specification ) |
| { |
| return new Specification<T>() |
| { |
| @Override |
| public boolean satisfiedBy( T instance ) |
| { |
| return !specification.satisfiedBy( instance ); |
| } |
| }; |
| } |
| |
| @SafeVarargs |
| public static <T> AndSpecification<T> and( final Specification<T>... specifications ) |
| { |
| return and( Iterables.iterable( specifications ) ); |
| } |
| |
| public static <T> AndSpecification<T> and( final Iterable<Specification<T>> specifications ) |
| { |
| return new AndSpecification<>( specifications ); |
| } |
| |
| @SafeVarargs |
| public static <T> OrSpecification<T> or( final Specification<T>... specifications ) |
| { |
| return or( Iterables.iterable( specifications ) ); |
| } |
| |
| public static <T> OrSpecification<T> or( final Iterable<Specification<T>> specifications ) |
| { |
| return new OrSpecification<>( specifications ); |
| } |
| |
| @SafeVarargs |
| public static <T> Specification<T> in( final T... allowed ) |
| { |
| return in( Iterables.iterable( allowed ) ); |
| } |
| |
| public static <T> Specification<T> in( final Iterable<T> allowed ) |
| { |
| return new Specification<T>() |
| { |
| @Override |
| public boolean satisfiedBy( T item ) |
| { |
| for( T allow : allowed ) |
| { |
| if( allow.equals( item ) ) |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| }; |
| } |
| |
| public static <T> Specification<T> notNull() |
| { |
| return new Specification<T>() |
| { |
| @Override |
| public boolean satisfiedBy( T item ) |
| { |
| return item != null; |
| } |
| }; |
| } |
| |
| public static <FROM, TO> Specification<FROM> translate( final Function<FROM, TO> function, |
| final Specification<? super TO> specification |
| ) |
| { |
| return new Specification<FROM>() |
| { |
| @Override |
| public boolean satisfiedBy( FROM item ) |
| { |
| return specification.satisfiedBy( function.map( item ) ); |
| } |
| }; |
| } |
| |
| /** |
| * AND Specification. |
| */ |
| public static class AndSpecification<T> |
| implements Specification<T> |
| { |
| private final Iterable<Specification<T>> specifications; |
| |
| private AndSpecification( Iterable<Specification<T>> specifications ) |
| { |
| this.specifications = specifications; |
| } |
| |
| @Override |
| public boolean satisfiedBy( T instance ) |
| { |
| for( Specification<T> specification : specifications ) |
| { |
| if( !specification.satisfiedBy( instance ) ) |
| { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| @SafeVarargs |
| public final AndSpecification<T> and( Specification<T>... specifications ) |
| { |
| Iterable<Specification<T>> iterable = Iterables.iterable( specifications ); |
| Iterable<Specification<T>> flatten = Iterables.flatten( this.specifications, iterable ); |
| return Specifications.and( flatten ); |
| } |
| |
| @SafeVarargs |
| public final OrSpecification<T> or( Specification<T>... specifications ) |
| { |
| return Specifications.or( Iterables.prepend( this, Iterables.iterable( specifications ) ) ); |
| } |
| } |
| |
| /** |
| * OR Specification. |
| */ |
| public static class OrSpecification<T> |
| implements Specification<T> |
| { |
| private final Iterable<Specification<T>> specifications; |
| |
| private OrSpecification( Iterable<Specification<T>> specifications ) |
| { |
| this.specifications = specifications; |
| } |
| |
| @Override |
| public boolean satisfiedBy( T instance ) |
| { |
| for( Specification<T> specification : specifications ) |
| { |
| if( specification.satisfiedBy( instance ) ) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| @SafeVarargs |
| public final AndSpecification<T> and( Specification<T>... specifications ) |
| { |
| return Specifications.and( Iterables.prepend( this, Iterables.iterable( specifications ) ) ); |
| } |
| |
| @SafeVarargs |
| public final OrSpecification<T> or( Specification<T>... specifications ) |
| { |
| Iterable<Specification<T>> iterable = Iterables.iterable( specifications ); |
| Iterable<Specification<T>> flatten = Iterables.flatten( this.specifications, iterable ); |
| return Specifications.or( flatten ); |
| } |
| } |
| |
| private Specifications() |
| { |
| } |
| |
| } |