<commit_before>package org.minimalj.backend;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.minimalj.application.Application;
import org.minimalj.security.Authorization;
import org.minimalj.security.Subject;
import org.minimalj.transaction.InputStreamTransaction;
import org.minimalj.transaction.OutputStreamTransaction;
import org.minimalj.transaction.Transaction;
import org.minimalj.util.LoggingRuntimeException;
import org.minimalj.util.SerializationContainer;
import org.minimalj.util.UnclosingOutputStream;

public class SocketBackendServer {
	private static final Logger LOG = Logger.getLogger(SocketBackendServer.class.getName());
	private static final String OK = null;
	private static final String NOT_AUTHORIZED = "Not authorized";
	
	private final int port;
	private final ThreadPoolExecutor executor;
	
	public SocketBackendServer(int port) {
		this.port = port;
		this.executor = new ThreadPoolExecutor(10, 30, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
	}
	
	public void run() {
		Thread.currentThread().setName("MjServer");
		try (ServerSocket serverSocket = new ServerSocket(port)) {
			accecptInvocations(serverSocket);
		} catch (IOException iox) {
			throw new LoggingRuntimeException(iox, LOG, "Could not create server socket");
		}
	}

	private void accecptInvocations(ServerSocket serverSocket) {
		while (true) {
			Socket socket;
			try {
				socket = serverSocket.accept();
				SocketBackendRunnable runnable = new SocketBackendRunnable(socket);
				executor.execute(runnable);
			} catch (IOException e) {
				LOG.log(Level.SEVERE, "Server socket couldn't accept connection", e);
			}
		}
	}
	
	private static class SocketBackendRunnable implements Runnable {
		private final Socket socket;

		public SocketBackendRunnable(Socket socket) {
			this.socket = socket;
		}

		@SuppressWarnings({ "rawtypes", "unchecked" })
		@Override
		public void run() {
			try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
				Serializable securityToken = (Serializable) ois.readObject();
				Subject subject =  Authorization.getCurrent().getUserByToken(securityToken);
				Subject.setCurrent(subject);
				
				Transaction transaction = (Transaction) ois.readObject();
				
				Object result, wrappedResult = null;
				if (transaction instanceof InputStreamTransaction) {
					InputStreamTransaction inputStreamTransaction = (InputStreamTransaction) transaction;
					inputStreamTransaction.setStream(ois);
				} 
				
				try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
					if (Authorization.isActive() && !Authorization.isAllowed(transaction)) {
						oos.writeObject(NOT_AUTHORIZED);
						return;
					}
					
					if (transaction instanceof OutputStreamTransaction) {
						OutputStreamTransaction outputStreamTransaction = (OutputStreamTransaction) transaction;
						outputStreamTransaction.setStream(new UnclosingOutputStream(oos));
					}
					try {
						result = Backend.execute(transaction);
						wrappedResult = SerializationContainer.wrap(result);<commit_msg>SocketBackendServer: removed redundant check<commit_after>package org.minimalj.backend;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.minimalj.application.Application;
import org.minimalj.security.Authorization;
import org.minimalj.security.Subject;
import org.minimalj.transaction.InputStreamTransaction;
import org.minimalj.transaction.OutputStreamTransaction;
import org.minimalj.transaction.Transaction;
import org.minimalj.util.LoggingRuntimeException;
import org.minimalj.util.SerializationContainer;
import org.minimalj.util.UnclosingOutputStream;

public class SocketBackendServer {
	private static final Logger LOG = Logger.getLogger(SocketBackendServer.class.getName());
	private static final String OK = null;
	private static final String NOT_AUTHORIZED = "Not authorized";
	
	private final int port;
	private final ThreadPoolExecutor executor;
	
	public SocketBackendServer(int port) {
		this.port = port;
		this.executor = new ThreadPoolExecutor(10, 30, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
	}
	
	public void run() {
		Thread.currentThread().setName("MjServer");
		try (ServerSocket serverSocket = new ServerSocket(port)) {
			accecptInvocations(serverSocket);
		} catch (IOException iox) {
			throw new LoggingRuntimeException(iox, LOG, "Could not create server socket");
		}
	}

	private void accecptInvocations(ServerSocket serverSocket) {
		while (true) {
			Socket socket;
			try {
				socket = serverSocket.accept();
				SocketBackendRunnable runnable = new SocketBackendRunnable(socket);
				executor.execute(runnable);
			} catch (IOException e) {
				LOG.log(Level.SEVERE, "Server socket couldn't accept connection", e);
			}
		}
	}
	
	private static class SocketBackendRunnable implements Runnable {
		private final Socket socket;

		public SocketBackendRunnable(Socket socket) {
			this.socket = socket;
		}

		@SuppressWarnings({ "rawtypes", "unchecked" })
		@Override
		public void run() {
			try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
				Serializable securityToken = (Serializable) ois.readObject();
				Subject subject =  Authorization.getCurrent().getUserByToken(securityToken);
				Subject.setCurrent(subject);
				
				Transaction transaction = (Transaction) ois.readObject();
				
				Object result, wrappedResult = null;
				if (transaction instanceof InputStreamTransaction) {
					InputStreamTransaction inputStreamTransaction = (InputStreamTransaction) transaction;
					inputStreamTransaction.setStream(ois);
				} 
				
				try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
					if (!Authorization.isAllowed(transaction)) {
						oos.writeObject(NOT_AUTHORIZED);
						return;
					}
					
					if (transaction instanceof OutputStreamTransaction) {
						OutputStreamTransaction outputStreamTransaction = (OutputStreamTransaction) transaction;
						outputStreamTransaction.setStream(new UnclosingOutputStream(oos));
					}
					try {
						result = Backend.execute(transaction);
						wrappedResult = SerializationContainer.wrap(result);
{'fraction_non_alphanumeric': 0.0919607556011129, 'fraction_numerical': 0.0017572118904671254, 'mean_word_length': 5.0603371783496005, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '7389723', 'n_tokens_mistral': 2162, 'n_tokens_neox': 1829, 'n_words': 421}