📄 sessionmanager.java
字号:
/**
* Add a session to the manager.
*
* @param session
*/
void addSession(ClientSession session) {
String resource = session.getAddress().getResource();
Presence presence = session.getPresence();
int priority = presence == null ? 0 : presence.getPriority();
resources.put(resource, session);
sortSession(resource, priority);
}
/**
* Sorts the session into the list based on priority
*
* @param resource The resource corresponding to the session to sort
* @param priority The priority to use for sorting
*/
private void sortSession(String resource, int priority) {
synchronized (priorityList) {
if (priorityList.size() > 0) {
Iterator<String> iter = priorityList.iterator();
for (int i = 0; iter.hasNext(); i++) {
ClientSession sess = resources.get(iter.next());
if (sess != null && sess.getPresence().getPriority() <= priority) {
priorityList.add(i, resource);
break;
}
}
}
if (!priorityList.contains(resource)) {
priorityList.addLast(resource);
}
}
}
/**
* Change the priority of a session associated with the sender.
*
* @param sender The sender who's session just changed priority
* @param priority The new priority for the session
*/
public void changePriority(JID sender, int priority) {
String resource = sender.getResource();
if (resources.containsKey(resource)) {
synchronized (priorityList) {
priorityList.remove(resource);
sortSession(resource, priority);
}
}
}
/**
* Remove a session from the manager.
*
* @param session The session to remove.
* @return true if the session was present in the map and was removed.
*/
boolean removeSession(Session session) {
String resource = session.getAddress().getResource();
boolean removed = resources.remove(resource) != null;
synchronized (priorityList) {
priorityList.remove(resource);
}
return removed;
}
/**
* Gets the session for the given resource.
*
* @param resource The resource describing the particular session
* @return The session for that resource or null if none found (use getDefaultSession() to obtain default)
*/
ClientSession getSession(String resource) {
return resources.get(resource);
}
/**
* Checks to see if a session for the given resource exists.
*
* @param resource The resource of the session we're checking
* @return True if we have a session corresponding to that resource
*/
boolean hasSession(String resource) {
return resources.containsKey(resource);
}
/**
* Returns the default session for the user based on presence priority. It's possible to
* indicate if only available sessions (i.e. with an available presence) should be
* included in the search.
*
* @param filterAvailable flag that indicates if only available sessions should be
* considered.
* @return The default session for the user.
*/
ClientSession getDefaultSession(boolean filterAvailable) {
if (priorityList.isEmpty()) {
return null;
}
if (!filterAvailable) {
return resources.get(priorityList.getFirst());
}
else {
synchronized (priorityList) {
for (int i=0; i < priorityList.size(); i++) {
ClientSession s = resources.get(priorityList.get(i));
if (s != null && s.getPresence().isAvailable()) {
return s;
}
}
}
return null;
}
}
/**
* Determines if this map is empty or not.
*
* @return True if the map contains no entries
*/
boolean isEmpty() {
return resources.isEmpty();
}
/**
* Broadcast to all resources for the given user
*
* @param packet
*/
private void broadcast(Packet packet) throws UnauthorizedException, PacketException {
for (Session session : resources.values()) {
packet.setTo(session.getAddress());
session.process(packet);
}
}
/**
* Create an iterator over all sessions for the user.
* We create a new list to generate the iterator so other threads
* may safely alter the session map without affecting the iterator.
*
* @return An iterator of all sessions
*/
public Collection<ClientSession> getSessions() {
return resources.values();
}
/**
* Returns a collection of all the sessions whose presence is available.
*
* @return a collection of all the sessions whose presence is available.
*/
public Collection<ClientSession> getAvailableSessions() {
LinkedList<ClientSession> list = new LinkedList<ClientSession>();
for (ClientSession session : resources.values()) {
if (session.getPresence().isAvailable()) {
list.add(session);
}
}
return list;
}
/**
* This specified session has received an available presence so we need to recalculate the
* order of the sessions so we can have update the default session.
*
* @param session the session that received an available presence.
*/
public void sessionAvailable(ClientSession session) {
changePriority(session.getAddress(), session.getPresence().getPriority());
}
/**
* This specified session has received an unavailable presence so we need to recalculate the
* order of the sessions so we can have update the default session.
*
* @param session the session that received an unavailable presence.
*/
public void sessionUnavailable(ClientSession session) {
changePriority(session.getAddress(), 0);
}
}
/**
* Returns a randomly created ID to be used in a stream element.
*
* @return a randomly created ID to be used in a stream element.
*/
public StreamID nextStreamID() {
return streamIDFactory.createStreamID();
}
/**
* Creates a new <tt>ClientSession</tt>. The new Client session will have a newly created
* stream ID.
*
* @param conn the connection to create the session from.
* @return a newly created session.
* @throws UnauthorizedException
*/
public ClientSession createClientSession(Connection conn) throws UnauthorizedException {
return createClientSession(conn, nextStreamID());
}
/**
* Creates a new <tt>ClientSession</tt> with the specified streamID.
*
* @param conn the connection to create the session from.
* @param id the streamID to use for the new session.
* @return a newly created session.
* @throws UnauthorizedException
*/
public ClientSession createClientSession(Connection conn, StreamID id)
throws UnauthorizedException {
if (serverName == null) {
throw new UnauthorizedException("Server not initialized");
}
ClientSession session = new ClientSession(serverName, conn, id);
conn.init(session);
// Register to receive close notification on this session so we can
// remove and also send an unavailable presence if it wasn't
// sent before
conn.registerCloseListener(clientSessionListener, session);
// Add to pre-authenticated sessions.
preAuthenticatedSessions.put(session.getAddress().getResource(), session);
// Increment the counter of user sessions
usersSessionsCounter.incrementAndGet();
return session;
}
public Session createComponentSession(Connection conn) throws UnauthorizedException {
if (serverName == null) {
throw new UnauthorizedException("Server not initialized");
}
StreamID id = nextStreamID();
ComponentSession session = new ComponentSession(serverName, conn, id);
conn.init(session);
// Register to receive close notification on this session so we can
// remove the external component from the list of components
conn.registerCloseListener(componentSessionListener, session);
// Add to component session.
componentsSessions.add(session);
return session;
}
/**
* Creates a session for a remote server. The session should be created only after the
* remote server has been authenticated either using "server dialback" or SASL.
*
* @param conn the connection to the remote server.
* @param id the stream ID used in the stream element when authenticating the server.
* @return the newly created {@link IncomingServerSession}.
* @throws UnauthorizedException if the local server has not been initialized yet.
*/
public IncomingServerSession createIncomingServerSession(Connection conn, StreamID id)
throws UnauthorizedException {
if (serverName == null) {
throw new UnauthorizedException("Server not initialized");
}
IncomingServerSession session = new IncomingServerSession(serverName, conn, id);
conn.init(session);
// Register to receive close notification on this session so we can
// remove its route from the sessions set
conn.registerCloseListener(incomingServerListener, session);
return session;
}
/**
* Notification message that a new OutgoingServerSession has been created. Register a listener
* that will react when the connection gets closed.
*
* @param session the newly created OutgoingServerSession.
*/
public void outgoingServerSessionCreated(OutgoingServerSession session) {
// Register to receive close notification on this session so we can
// remove its route from the sessions set
session.getConnection().registerCloseListener(outgoingServerListener, session);
}
/**
* Registers that a server session originated by a remote server is hosting a given hostname.
* Notice that the remote server may be hosting several subdomains as well as virtual hosts so
* the same IncomingServerSession may be associated with many keys. If the remote server
* creates many sessions to this server (eg. one for each subdomain) then associate all
* the sessions with the originating server that created all the sessions.
*
* @param hostname the hostname that is being served by the remote server.
* @param session the incoming server session to the remote server.
*/
public void registerIncomingServerSession(String hostname, IncomingServerSession session) {
synchronized (incomingServerSessions) {
List<IncomingServerSession> sessions = incomingServerSessions.get(hostname);
if (sessions == null || sessions.isEmpty()) {
// First session from the remote server to this server so create a
// new association
List<IncomingServerSession> value = new CopyOnWriteArrayList<IncomingServerSession>();
value.add(session);
incomingServerSessions.put(hostname, value);
}
else {
// Add new session to the existing list of sessions originated by
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -