/*
 * Copyright (C) 2012 - 2012 NHN Corporation
 * All rights reserved.
 *
 * This file is part of The nGrinder software distribution. Refer to
 * the file LICENSE which is part of The nGrinder distribution for
 * licensing details. The nGrinder distribution is available on the
 * Internet at http://nhnopensource.org/ngrinder
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.ngrinder.perftest.repository;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.ngrinder.model.User;
import org.ngrinder.perftest.model.PerfTest;
import org.ngrinder.perftest.model.Status;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;

/**
 * {@link PerfTest} Specification for more elaborated search.
 * 
 * @author JunHo Yoon
 * @since 3.0
 */
public class PerfTestSpecification {
	/**
	 * Get the Specification which check the {@link PerfTest} has one of given statuses.
	 * 
	 * @param statuses
	 *            status set
	 * @return {@link Specification}
	 */
	public static Specification<PerfTest> statusSetEqual(final Status... statuses) {
		return new Specification<PerfTest>() {
			@Override
			public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return root.get("status").in((Object[]) statuses);
			}
		};
	}

	/**
	 * Get the Specification which check the {@link PerfTest} has one of given id.
	 * 
	 * @param statuses
	 *            status set
	 * @return {@link Specification}
	 */
	public static Specification<PerfTest> idSetEqual(final Integer[] ids) {
		return new Specification<PerfTest>() {
			@Override
			public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return root.get("id").in((Object[]) ids);
			}
		};
	}

	/**
	 * Get the Specification which check the {@link PerfTest} has given id.
	 * 
	 * @param statuses
	 *            status set
	 * @return {@link Specification}
	 */
	public static Specification<PerfTest> idEqual(final Integer id) {
		return new Specification<PerfTest>() {
			@Override
			public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.equal(root.get("id"), id);
			}
		};
	}

	/**
	 * Get the Specification which provide empty predicate. This is for the base element for "and" or "or" combination.
	 * 
	 * @return {@link Specification}
	 */
	public static Specification<PerfTest> emptyPredicate() {
		return new Specification<PerfTest>() {
			@Override
			public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return root.get("id").isNotNull();
			}
		};
	}

	/**
	 * Get the search {@link Specification} for testName and description fields.
	 * 
	 * @param queryString
	 *            query String
	 * @return {@link Specification}
	 */
	public static Specification<PerfTest> likeTestNameOrDescription(final String queryString) {
		return new Specification<PerfTest>() {
			@Override
			public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				String queryStr = ("%" + queryString + "%").toLowerCase();
				return cb.or(cb.like(cb.lower(root.get("testName").as(String.class)), queryStr),
						cb.like(root.get("description").as(String.class), queryStr));
			}
		};
	}

	/**
	 * Get createBy specification to get the {@link PerfTest} whose creator or last modifier is the given user
	 * 
	 * @param user
	 *            user
	 * @return {@link Specification}
	 */
	public static Specification<PerfTest> lastModifiedOrCreatedBy(final User user) {
		return new Specification<PerfTest>() {
			@Override
			public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.or(cb.equal(root.get("lastModifiedBy"), user), cb.equal(root.get("createdBy"), user));
			}
		};
	}

	/**
	 * Get sort sorted by ascending "createdDate".
	 * 
	 * @return Sort
	 */
	public static Sort sortByCreatedDate() {
		return new Sort(Sort.Direction.ASC, "createdDate");
	}

}

@@ -4670,18 +4670,20 @@
 Modified
-By
+User
 %22), user
@@ -4711,18 +4711,20 @@
 %22created
-By
+User
 %22), user

Fix test failure