<commit_before>/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2005-2016 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.rpc;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityTransaction;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.shiro.authz.AuthorizationException;
import org.postgresql.util.PSQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.axelor.auth.AuthSecurityException;
import com.axelor.auth.AuthUtils;
import com.axelor.db.JpaSecurity.AccessType;
import com.axelor.db.JpaSupport;
import com.axelor.db.Model;
import com.axelor.i18n.I18n;

public class ResponseInterceptor extends JpaSupport implements MethodInterceptor {

	private final Logger log = LoggerFactory.getLogger(ResponseInterceptor.class);

	private final ThreadLocal<Boolean> running = new ThreadLocal<Boolean>();

	@Override
	public Object invoke(final MethodInvocation invocation) throws Throwable {

		if (running.get() == Boolean.TRUE) {
			return invocation.proceed();
		}

		log.trace("Web Service: {}", invocation.getMethod());

		Response response = null;

		running.set(true);
		try {
			response = (Response) invocation.proceed();
		} catch (Exception e) {
			EntityTransaction txn = getEntityManager().getTransaction();
			if (txn.isActive()) {
				txn.rollback();
			} else if (e instanceof PersistenceException) {
				// recover the transaction
				try {
					txn.begin();
				} catch(Exception ex){}
			}
			response = new Response();
			response = onException(e, response);
		} finally {
			running.remove();
		}
		return response;
	}

	private Response onException(Throwable ex, Response response) {

		if (ex instanceof AuthorizationException) {
			return onAuthorizationException((AuthorizationException) ex, response);
		}
		if (ex instanceof AuthSecurityException) {
			return onAuthSecurityException((AuthSecurityException) ex, response);
		}
		if (ex instanceof OptimisticLockException) {
			return onOptimisticLockException((OptimisticLockException) ex, response);
		}
		if (ex instanceof ConstraintViolationException) {
			return onConstraintViolationException((ConstraintViolationException) ex, response);
		}
		if (ex instanceof SQLException) {
			return onSQLException((SQLException) ex, response);
		}
		if (ex.getCause() != null) {<commit_msg>Fix transaction cleanup issue<commit_after>/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2005-2016 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.rpc;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityTransaction;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.shiro.authz.AuthorizationException;
import org.postgresql.util.PSQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.axelor.auth.AuthSecurityException;
import com.axelor.auth.AuthUtils;
import com.axelor.db.JpaSecurity.AccessType;
import com.axelor.db.JpaSupport;
import com.axelor.db.Model;
import com.axelor.i18n.I18n;

public class ResponseInterceptor extends JpaSupport implements MethodInterceptor {

	private final Logger log = LoggerFactory.getLogger(ResponseInterceptor.class);

	private final ThreadLocal<Boolean> running = new ThreadLocal<Boolean>();

	@Override
	public Object invoke(final MethodInvocation invocation) throws Throwable {

		if (running.get() == Boolean.TRUE) {
			return invocation.proceed();
		}

		log.trace("Web Service: {}", invocation.getMethod());

		Response response = null;

		running.set(true);
		try {
			response = (Response) invocation.proceed();
		} catch (Exception e) {
			final EntityTransaction txn = getEntityManager().getTransaction();
			if (txn.isActive()) {
				txn.rollback();
			} else if (e instanceof PersistenceException) {
				// recover the transaction
				try {
					txn.begin();
				} catch(Exception ex){}
			}
			try {
				response = new Response();
				response = onException(e, response);
			} finally {
				if (txn.isActive()) {
					txn.rollback();
				}
			}
		} finally {
			running.remove();
		}
		return response;
	}

	private Response onException(Throwable ex, Response response) {

		if (ex instanceof AuthorizationException) {
			return onAuthorizationException((AuthorizationException) ex, response);
		}
		if (ex instanceof AuthSecurityException) {
			return onAuthSecurityException((AuthSecurityException) ex, response);
		}
		if (ex instanceof OptimisticLockException) {
			return onOptimisticLockException((OptimisticLockException) ex, response);
		}
		if (ex instanceof ConstraintViolationException) {
			return onConstraintViolationException((ConstraintViolationException) ex, response);
		}
		if (ex instanceof SQLException) {
			return onSQLException((SQLException) ex, response);
		}
		if (ex.getCause() != null) {
{'fraction_non_alphanumeric': 0.09625912408759124, 'fraction_numerical': 0.004562043795620438, 'mean_word_length': 4.729094076655052, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '7659910', 'n_tokens_mistral': 2027, 'n_tokens_neox': 1838, 'n_words': 537}