/*
* Copyright 2015 herd contributors
*
* 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.finra.herd.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import org.finra.herd.dao.NamespaceDao;
import org.finra.herd.model.api.xml.NamespaceKey;
import org.finra.herd.model.jpa.NamespaceEntity;
import org.finra.herd.model.jpa.NamespaceEntity_;

@Repository
public class NamespaceDaoImpl extends AbstractHerdDao implements NamespaceDao
{
    private static final Logger LOGGER = LoggerFactory.getLogger(NamespaceDaoImpl.class);

    @Override
    public NamespaceEntity getNamespaceByKey(NamespaceKey namespaceKey)
    {
        return getNamespaceByCd(namespaceKey.getNamespaceCode());
    }

    @Override
    public NamespaceEntity getNamespaceByCd(String namespaceCode)
    {
        StringBuilder stackTraceBuilder = new StringBuilder();
        for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
            stackTraceBuilder.append(ste);
        }

        LOGGER.info("getNamespaceByCd: {}", stackTraceBuilder);

        // Create the criteria builder and the criteria.
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<NamespaceEntity> criteria = builder.createQuery(NamespaceEntity.class);

        // The criteria root is the namespace.
        Root<NamespaceEntity> namespaceEntity = criteria.from(NamespaceEntity.class);

        // Create the standard restrictions (i.e. the standard where clauses).
        Predicate queryRestriction = builder.equal(builder.upper(namespaceEntity.get(NamespaceEntity_.code)), namespaceCode.toUpperCase());

        criteria.select(namespaceEntity).where(queryRestriction);

        HashMap<String, Object> properties = new HashMap<>();

        return executeSingleResultQuery(criteria, String.format("Found more than one namespace with namespaceCode=\"%s\".", namespaceCode, properties));
    }

    @Override
    public List<NamespaceKey> getNamespaces()
    {
        // Create the criteria builder and a tuple style criteria query.
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<String> criteria = builder.createQuery(String.class);

        // The criteria root is the business object definition.
        Root<NamespaceEntity> namespaceEntity = criteria.from(NamespaceEntity.class);

        // Get the columns.
        Path<String> namespaceCodeColumn = namespaceEntity.get(NamespaceEntity_.code);

        // Add the select clause.
        criteria.select(namespaceCodeColumn);

        // Add the order by clause.
        criteria.orderBy(builder.asc(namespaceCodeColumn));

        // Run the query to get a list of namespace codes back.
        List<String> namespaceCodes = entityManager.createQuery(criteria).getResultList();

        // Populate the "keys" objects from the returned namespace codes.
        List<NamespaceKey> namespaceKeys = new ArrayList<>();
        for (String namespaceCode : namespaceCodes)
        {
            namespaceKeys.add(new NamespaceKey(namespaceCode));
        }

        return namespaceKeys;
    }
}

@@ -922,65 +922,8 @@
 t;%0A%0A
-import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 impo
@@ -968,16 +968,16 @@
 sitory;%0A
+
 %0Aimport 
@@ -1255,99 +1255,8 @@
 o%0A%7B%0A
-    private static final Logger LOGGER = LoggerFactory.getLogger(NamespaceDaoImpl.class);%0A%0A
     
@@ -1506,269 +1506,8 @@
   %7B%0A
-        StringBuilder stackTraceBuilder = new StringBuilder();%0A        for (StackTraceElement ste : Thread.currentThread().getStackTrace()) %7B%0A            stackTraceBuilder.append(ste);%0A        %7D%0A%0A        LOGGER.info(%22getNamespaceByCd: %7B%7D%22, stackTraceBuilder);%0A%0A
     
@@ -2141,24 +2141,24 @@
 triction);%0A%0A
-
         Hash
@@ -2206,16 +2206,73 @@
 Map%3C%3E();
+%0A        properties.put(%22org.hibernate.cacheable%22, true);
 %0A%0A      

Revert "DM-15501: FactoryCQ - Eliminate frequent calls to namespace get query"