<commit_before>package org.bimserver.notifications;

/******************************************************************************
 * Copyright (C) 2009-2019  BIMserver.org
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * 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 {@literal<http://www.gnu.org/licenses/>}.
 *****************************************************************************/

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.bimserver.BimServer;
import org.bimserver.client.Channel;
import org.bimserver.client.DirectChannel;
import org.bimserver.client.SimpleTokenHolder;
import org.bimserver.client.json.JsonChannel;
import org.bimserver.client.json.JsonSocketReflectorFactory;
import org.bimserver.interfaces.objects.SLogAction;
import org.bimserver.interfaces.objects.SProgressTopicType;
import org.bimserver.models.store.ServerSettings;
import org.bimserver.models.store.Service;
import org.bimserver.shared.ChannelConnectionException;
import org.bimserver.shared.exceptions.UserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NotificationsManager {
	private static final Logger LOGGER = LoggerFactory.getLogger(NotificationsManager.class);

	private final NewRevisionTopic newRevisionTopic = new NewRevisionTopic(this);
	private final NewProjectTopic newProjectTopic = new NewProjectTopic(this);
	private final NewUserTopic newUserTopic = new NewUserTopic(this);
	private final Map<NewExtendedDataOnRevisionTopicKey, NewExtendedDataOnRevisionTopic> newExtendedDataOnRevisionTopics = new HashMap<NewExtendedDataOnRevisionTopicKey, NewExtendedDataOnRevisionTopic>();
	private final Map<NewRevisionOnSpecificProjectTopicKey, NewRevisionOnSpecificProjectTopic> newRevisionOnSpecificProjectTopics = new HashMap<NewRevisionOnSpecificProjectTopicKey, NewRevisionOnSpecificProjectTopic>();

	// These are for keeping track of new/removed progress topics
	private final Map<ChangeProgressTopicOnProjectTopicKey, ChangeProgressTopicOnProjectTopic> changeProgressTopicOnProjectTopics = new HashMap<ChangeProgressTopicOnProjectTopicKey, ChangeProgressTopicOnProjectTopic>();
	private final Map<ChangeProgressTopicOnRevisionTopicKey, ChangeProgressTopicOnRevisionTopic> changeProgressTopicOnRevisionTopics = new HashMap<ChangeProgressTopicOnRevisionTopicKey, ChangeProgressTopicOnRevisionTopic>();
	private final ChangeProgressTopicOnServerTopic changeProgressTopicOnServerTopic = new ChangeProgressTopicOnServerTopic(this);

	// All progress topics have an id for easy referencing
	private final Map<Long, ProgressTopic> progressTopicsById = new HashMap<Long, ProgressTopic>();
	
	// These are for keeping track of actual progress on projects/revisions
	private final Map<ProgressOnRevisionTopicKey, Set<ProgressOnRevisionTopic>> progressOnRevisionTopics = new HashMap<ProgressOnRevisionTopicKey, Set<ProgressOnRevisionTopic>>();
	private final Map<ProgressOnProjectTopicKey, Set<ProgressOnProjectTopic>> progressOnProjectTopics = new HashMap<ProgressOnProjectTopicKey, Set<ProgressOnProjectTopic>>();

	private final JsonSocketReflectorFactory jsonSocketReflectorFactory;
	private final BimServer bimServer;
	private String url;
	private final NotificationsProcessor notificationsProcessor;

	public NotificationsManager(BimServer bimServer, JsonSocketReflectorFactory jsonSocketReflectorFactory) {
		this.jsonSocketReflectorFactory = jsonSocketReflectorFactory;<commit_msg>Improved concurrent operation of NotificationsManager<commit_after>package org.bimserver.notifications;

/******************************************************************************
 * Copyright (C) 2009-2019  BIMserver.org
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * 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 {@literal<http://www.gnu.org/licenses/>}.
 *****************************************************************************/

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.bimserver.BimServer;
import org.bimserver.client.Channel;
import org.bimserver.client.DirectChannel;
import org.bimserver.client.SimpleTokenHolder;
import org.bimserver.client.json.JsonChannel;
import org.bimserver.client.json.JsonSocketReflectorFactory;
import org.bimserver.interfaces.objects.SLogAction;
import org.bimserver.interfaces.objects.SProgressTopicType;
import org.bimserver.models.store.ServerSettings;
import org.bimserver.models.store.Service;
import org.bimserver.shared.ChannelConnectionException;
import org.bimserver.shared.exceptions.UserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NotificationsManager {
	private static final Logger LOGGER = LoggerFactory.getLogger(NotificationsManager.class);

	private final NewRevisionTopic newRevisionTopic = new NewRevisionTopic(this);
	private final NewProjectTopic newProjectTopic = new NewProjectTopic(this);
	private final NewUserTopic newUserTopic = new NewUserTopic(this);
	private final Map<NewExtendedDataOnRevisionTopicKey, NewExtendedDataOnRevisionTopic> newExtendedDataOnRevisionTopics = Collections.synchronizedMap(new HashMap<NewExtendedDataOnRevisionTopicKey, NewExtendedDataOnRevisionTopic>());
	private final Map<NewRevisionOnSpecificProjectTopicKey, NewRevisionOnSpecificProjectTopic> newRevisionOnSpecificProjectTopics = Collections.synchronizedMap(new HashMap<NewRevisionOnSpecificProjectTopicKey, NewRevisionOnSpecificProjectTopic>());

	// These are for keeping track of new/removed progress topics
	private final Map<ChangeProgressTopicOnProjectTopicKey, ChangeProgressTopicOnProjectTopic> changeProgressTopicOnProjectTopics = Collections.synchronizedMap(new HashMap<ChangeProgressTopicOnProjectTopicKey, ChangeProgressTopicOnProjectTopic>());
	private final Map<ChangeProgressTopicOnRevisionTopicKey, ChangeProgressTopicOnRevisionTopic> changeProgressTopicOnRevisionTopics = Collections.synchronizedMap(new HashMap<ChangeProgressTopicOnRevisionTopicKey, ChangeProgressTopicOnRevisionTopic>());
	private final ChangeProgressTopicOnServerTopic changeProgressTopicOnServerTopic = new ChangeProgressTopicOnServerTopic(this);

	// All progress topics have an id for easy referencing
	private final Map<Long, ProgressTopic> progressTopicsById = Collections.synchronizedMap(new HashMap<Long, ProgressTopic>());
	
	// These are for keeping track of actual progress on projects/revisions
	private final Map<ProgressOnRevisionTopicKey, Set<ProgressOnRevisionTopic>> progressOnRevisionTopics = Collections.synchronizedMap(new HashMap<ProgressOnRevisionTopicKey, Set<ProgressOnRevisionTopic>>());
	private final Map<ProgressOnProjectTopicKey, Set<ProgressOnProjectTopic>> progressOnProjectTopics = Collections.synchronizedMap(new HashMap<ProgressOnProjectTopicKey, Set<ProgressOnProjectTopic>>());

	private final JsonSocketReflectorFactory jsonSocketReflectorFactory;
	private final BimServer bimServer;
	private String url;
	private final NotificationsProcessor notificationsProcessor;

	public NotificationsManager(BimServer bimServer, JsonSocketReflectorFactory jsonSocketReflectorFactory) {
		this.jsonSocketReflectorFactory = jsonSocketReflectorFactory;
{'fraction_non_alphanumeric': 0.09896760412958348, 'fraction_numerical': 0.0026106562240417706, 'mean_word_length': 7.985074626865671, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, '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': '5034649', 'n_tokens_mistral': 2168, 'n_tokens_neox': 2056, 'n_words': 579}