<commit_before>package pro.taskana.simplehistory.impl;

import java.sql.SQLException;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.SqlSessionManager;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.simplehistory.TaskanaHistoryEngine;
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryEventMapper;
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryQueryMapper;
import pro.taskana.simplehistory.impl.task.TaskHistoryEventMapper;
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryEventMapper;
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryQueryMapper;
import pro.taskana.spi.history.api.TaskanaHistory;

/** This is the implementation of TaskanaHistoryEngine. */
public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {

  protected static final ThreadLocal<Deque<SqlSessionManager>> SESSION_STACK = new ThreadLocal<>();
  private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaHistoryEngineImpl.class);
  private static final String DEFAULT = "default";
  private final SqlSessionManager sessionManager;
  private final TaskanaEngineConfiguration taskanaEngineConfiguration;
  private final TaskanaEngine taskanaEngine;
  private TransactionFactory transactionFactory;
  private TaskanaHistory taskanaHistoryService;

  protected TaskanaHistoryEngineImpl(TaskanaEngine taskanaEngine) {
    this.taskanaEngineConfiguration = taskanaEngine.getConfiguration();
    this.taskanaEngine = taskanaEngine;

    createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
    sessionManager = createSqlSessionManager();
  }

  public static TaskanaHistoryEngineImpl createTaskanaEngine(TaskanaEngine taskanaEngine) {
    return new TaskanaHistoryEngineImpl(taskanaEngine);
  }

  @Override
  public TaskanaHistory getTaskanaHistoryService() {
    if (taskanaHistoryService == null) {
      SimpleHistoryServiceImpl historyService = new SimpleHistoryServiceImpl();
      historyService.initialize(taskanaEngine);
      this.taskanaHistoryService = historyService;
    }
    return this.taskanaHistoryService;
  }

  public boolean isUserInRole(TaskanaRole... roles) {
    if (!getConfiguration().isSecurityEnabled()) {
      return true;
    }

    Set<String> rolesMembers =
        Arrays.stream(roles)
            .map(role -> getConfiguration().getRoleMap().get(role))
            .collect(HashSet::new, Set::addAll, Set::addAll);

    return taskanaEngine.getCurrentUserContext().getAccessIds().stream()
        .anyMatch(rolesMembers::contains);
  }

  public void checkRoleMembership(TaskanaRole... roles) throws NotAuthorizedException {
    if (!isUserInRole(roles)) {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug(
            "Throwing NotAuthorizedException because accessIds {} are not member of roles {}",
            taskanaEngine.getCurrentUserContext().getAccessIds(),
            Arrays.toString(roles));
      }
      throw new NotAuthorizedException(
          "current user is not member of role(s) " + Arrays.toString(roles),
          taskanaEngine.getCurrentUserContext().getUserid());
    }
  }

  public TaskanaEngineConfiguration getConfiguration() {
    return this.taskanaEngineConfiguration;
  }

  protected SqlSessionManager createSqlSessionManager() {
    Environment environment =
        new Environment(
            DEFAULT, this.transactionFactory, taskanaEngineConfiguration.getDatasource());
    Configuration configuration = new Configuration(environment);

    // add mappers
    configuration.addMapper(TaskHistoryEventMapper.class);
    configuration.addMapper(TaskHistoryQueryMapper.class);<commit_msg>TSK-1668: simplehistory-provider now presisting timestamps at UTC<commit_after>package pro.taskana.simplehistory.impl;

import java.sql.SQLException;
import java.time.Instant;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.SqlSessionManager;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
import org.apache.ibatis.type.JdbcType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.persistence.InstantTypeHandler;
import pro.taskana.common.internal.persistence.MapTypeHandler;
import pro.taskana.simplehistory.TaskanaHistoryEngine;
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryEventMapper;
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryQueryMapper;
import pro.taskana.simplehistory.impl.task.TaskHistoryEventMapper;
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryEventMapper;
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryQueryMapper;
import pro.taskana.spi.history.api.TaskanaHistory;

/** This is the implementation of TaskanaHistoryEngine. */
public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {

  protected static final ThreadLocal<Deque<SqlSessionManager>> SESSION_STACK = new ThreadLocal<>();
  private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaHistoryEngineImpl.class);
  private static final String DEFAULT = "default";
  private final SqlSessionManager sessionManager;
  private final TaskanaEngineConfiguration taskanaEngineConfiguration;
  private final TaskanaEngine taskanaEngine;
  private TransactionFactory transactionFactory;
  private TaskanaHistory taskanaHistoryService;

  protected TaskanaHistoryEngineImpl(TaskanaEngine taskanaEngine) {
    this.taskanaEngineConfiguration = taskanaEngine.getConfiguration();
    this.taskanaEngine = taskanaEngine;

    createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
    sessionManager = createSqlSessionManager();
  }

  public static TaskanaHistoryEngineImpl createTaskanaEngine(TaskanaEngine taskanaEngine) {
    return new TaskanaHistoryEngineImpl(taskanaEngine);
  }

  @Override
  public TaskanaHistory getTaskanaHistoryService() {
    if (taskanaHistoryService == null) {
      SimpleHistoryServiceImpl historyService = new SimpleHistoryServiceImpl();
      historyService.initialize(taskanaEngine);
      this.taskanaHistoryService = historyService;
    }
    return this.taskanaHistoryService;
  }

  public boolean isUserInRole(TaskanaRole... roles) {
    if (!getConfiguration().isSecurityEnabled()) {
      return true;
    }

    Set<String> rolesMembers =
        Arrays.stream(roles)
            .map(role -> getConfiguration().getRoleMap().get(role))
            .collect(HashSet::new, Set::addAll, Set::addAll);

    return taskanaEngine.getCurrentUserContext().getAccessIds().stream()
        .anyMatch(rolesMembers::contains);
  }

  public void checkRoleMembership(TaskanaRole... roles) throws NotAuthorizedException {
    if (!isUserInRole(roles)) {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug(
            "Throwing NotAuthorizedException because accessIds {} are not member of roles {}",
            taskanaEngine.getCurrentUserContext().getAccessIds(),
            Arrays.toString(roles));
      }
      throw new NotAuthorizedException(
          "current user is not member of role(s) " + Arrays.toString(roles),
          taskanaEngine.getCurrentUserContext().getUserid());
    }
  }

  public TaskanaEngineConfiguration getConfiguration() {
    return this.taskanaEngineConfiguration;
  }

  protected SqlSessionManager createSqlSessionManager() {
    Environment environment =
        new Environment(
            DEFAULT, this.transactionFactory, taskanaEngineConfiguration.getDatasource());
    Configuration configuration = new Configuration(environment);

    // register type handlers
    configuration.getTypeHandlerRegistry().register(new MapTypeHandler());
    configuration.getTypeHandlerRegistry().register(Instant.class, new InstantTypeHandler());
    configuration.getTypeHandlerRegistry().register(JdbcType.TIMESTAMP, new InstantTypeHandler());

    // add mappers
    configuration.addMapper(TaskHistoryEventMapper.class);
    configuration.addMapper(TaskHistoryQueryMapper.class);
{'fraction_non_alphanumeric': 0.08653146125845033, 'fraction_numerical': 0.0008320332813312533, 'mean_word_length': 5.35978835978836, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6726482', 'n_tokens_mistral': 2525, 'n_tokens_neox': 2524, 'n_words': 460}