// Copyright 2004-2014 Jim Voris
//
// 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 com.qumasoft.server;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This is a singleton class that we use to manage the licensing scheme for QVCS Enterprise. This really just keeps track of how many users log in. It used to enforce
* the terms of the license, but since things are now free, it just captures who is logged in, and from where, and puts that information into the activity journal.
*
* @author Jim Voris
*/
public final class LicenseManager {
// Create our logger object.
private static final Logger LOGGER = Logger.getLogger("com.qumasoft.server");
private static final LicenseManager LICENSE_MANAGER = new LicenseManager();
private final Map<String, Integer> userCollection;
private final Map<String, Integer> connectionMap = Collections.synchronizedMap(new TreeMap<String, Integer>());
/**
* Creates a new instance of LicenseManager.
*/
private LicenseManager() {
userCollection = Collections.synchronizedMap(new TreeMap<String, Integer>());
}
/**
* Return the singleton instance of the license manager.
*
* @return the singleton instance of the license manager.
*/
public static LicenseManager getInstance() {
return LICENSE_MANAGER;
}
/**
* Called to login another user to the server. Return true if adding the user is allowed. Return false
* if the customer does not have enough concurrent users on their license to support this additional user.
*
* @param message where to return an error explanation if there is one.
* @param userName the user's name.
* @param clientIPAddress the client IP address.
* @return true. The license manager always allows a login.
*/
public synchronized boolean loginUser(AtomicReference<String> message, String userName, String clientIPAddress) {
if (connectionMap.containsKey(clientIPAddress)) {
Integer ipUseCount = connectionMap.get(clientIPAddress);
connectionMap.put(clientIPAddress, Integer.valueOf(1 + ipUseCount.intValue()));
} else {
connectionMap.put(clientIPAddress, Integer.valueOf(1));
}
if (userCollection.containsKey(userName)) {
Integer userLoginCount = userCollection.get(userName);
userLoginCount = Integer.valueOf(1 + userLoginCount.intValue());
userCollection.put(userName, userLoginCount);
} else {
userCollection.put(userName, Integer.valueOf(1));
}
String loginMessage = "User: [" + userName + "] logged in from IP address [" + clientIPAddress + "] Concurrent user count: [" + userCollection.size() + "]";
LOGGER.log(Level.INFO, loginMessage);
ActivityJournalManager.getInstance().addJournalEntry(loginMessage);
return true;
}
/**
* Called when a user logs out, or otherwise disconnects from the server.
*
* @param userName the user's name.
* @param clientIPAddress the user's client IP address.
*/
public synchronized void logoutUser(String userName, final String clientIPAddress) {
if (connectionMap.size() > 0) {
Integer useCount = connectionMap.get(clientIPAddress);
if (useCount.intValue() == 1) {
connectionMap.remove(clientIPAddress);
} else {
useCount = Integer.valueOf(useCount.intValue() - 1);
connectionMap.put(clientIPAddress, useCount);
}
}
if (userCollection.size() > 0) {
Integer userLoginCount = userCollection.get(userName);
if (userLoginCount.intValue() == 1) {
userCollection.remove(userName);
} else {
userLoginCount = Integer.valueOf(userLoginCount.intValue() - 1);
userCollection.put(userName, userLoginCount);
}
}
String message = "User: [" + userName + "] logged out from IP address [" + clientIPAddress + "] Concurrent user count: " + userCollection.size();
LOGGER.log(Level.INFO, message);
ActivityJournalManager.getInstance().addJournalEntry(message);
}
/**
* Get the Set of currently logged in users.
* @return the Set of currently logged in users.
*/
public Set<String> getUserCollection() {
return userCollection.keySet();
}
}