Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2002-2014 the original author or authors.
   *
   * 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 org.springframework.messaging.simp.broker;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
A default, simple in-memory implementation of SubscriptionRegistry.

Author(s):
Rossen Stoyanchev
Sebastien Deleuze
Since:
4.0
 
Default maximum number of entries for the destination cache: 1024
 
 	public static final int DEFAULT_CACHE_LIMIT = 1024;


The maximum number of entries in the cache
 
 	private volatile int cacheLimit = ;
 
 	private PathMatcher pathMatcher = new AntPathMatcher();
 
 	private final DestinationCache destinationCache = new DestinationCache();
 
Specify the maximum number of entries for the resolved destination cache. Default is 1024.
 
 	public void setCacheLimit(int cacheLimit) {
 		this. = cacheLimit;
 	}

Return the maximum number of entries for the resolved destination cache.
 
 	public int getCacheLimit() {
 		return this.;
 	}

 
 	public void setPathMatcher(PathMatcher pathMatcher) {
 		this. = pathMatcher;
 	}

Return the configured org.springframework.util.PathMatcher.
 
 	public PathMatcher getPathMatcher() {
 		return this.;
 	}
 
 
 	protected void addSubscriptionInternal(String sessionIdString subsIdString destinationMessage<?> message) {
 		this..addSubscription(sessionIdsubsIddestination);
 		this..updateAfterNewSubscription(destinationsessionIdsubsId);
 	}
 
 	protected void removeSubscriptionInternal(String sessionIdString subsIdMessage<?> message) {
 		if (info != null) {
 			String destination = info.removeSubscription(subsId);
 			if (destination != null) {
			}
		}
	}
	public void unregisterAllSubscriptions(String sessionId) {
		if (info != null) {
				.debug("Unregistering subscriptions for sessionId=" + sessionId);
			}
		}
	}
	protected MultiValueMap<StringStringfindSubscriptionsInternal(String destinationMessage<?> message) {
		if (result != null) {
			return result;
		}
		result = new LinkedMultiValueMap<StringString>();
			for (String destinationPattern : info.getDestinations()) {
				if (this..match(destinationPatterndestination)) {
					for (String subscriptionId : info.getSubscriptions(destinationPattern)) {
						result.add(info.sessionIdsubscriptionId);
					}
				}
			}
		}
		if (!result.isEmpty()) {
			this..addSubscriptions(destinationresult);
		}
		return result;
	}
	public String toString() {
		return "[destinationCache=" + this. + ", subscriptionRegistry="
this. + "]";
	}


	private class DestinationCache {

Map from destination -> <sessionId, subscriptionId> for fast look-ups
		private final Map<StringMultiValueMap<StringString>> accessCache =
Map from destination -> <sessionId, subscriptionId> with locking
		private final Map<StringMultiValueMap<StringString>> updateCache =
					protected boolean removeEldestEntry(Map.Entry<StringMultiValueMap<StringString>> eldest) {
						return size() > getCacheLimit();
					}
				};
		public MultiValueMap<StringStringgetSubscriptions(String destination) {
			return this..get(destination);
		}
		public void addSubscriptions(String destinationMultiValueMap<StringStringsubscriptions) {
			synchronized (this.) {
				this..put(destinationsubscriptions);
				this..put(destinationnew LinkedMultiValueMap<StringString>(subscriptions));
			}
		}
		public void updateAfterNewSubscription(String destinationString sessionIdString subsId) {
			synchronized (this.) {
				for (Map.Entry<StringMultiValueMap<StringString>> entry : this..entrySet()) {
					String cachedDestination = entry.getKey();
					if (getPathMatcher().match(destinationcachedDestination)) {
						MultiValueMap<StringStringsubs = entry.getValue();
						subs.add(sessionIdsubsId);
						this..put(cachedDestinationnew LinkedMultiValueMap<StringString>(subs));
					}
				}
			}
		}
		public void updateAfterRemovedSubscription(String sessionIdString subsId) {
			synchronized (this.) {
				Set<StringdestinationsToRemove = new HashSet<String>();
				for (Map.Entry<StringMultiValueMap<StringString>> entry : this..entrySet()) {
					String destination = entry.getKey();
					MultiValueMap<StringStringsessionMap = entry.getValue();
					List<Stringsubscriptions = sessionMap.get(sessionId);
					if (subscriptions != null) {
						subscriptions.remove(subsId);
						if (subscriptions.isEmpty()) {
							sessionMap.remove(sessionId);
						}
						if (sessionMap.isEmpty()) {
							destinationsToRemove.add(destination);
						}
						else {
							this..put(destinationnew LinkedMultiValueMap<StringString>(sessionMap));
						}
					}
				}
				for (String destination : destinationsToRemove) {
					this..remove(destination);
					this..remove(destination);
				}
			}
		}
			synchronized (this.) {
				Set<StringdestinationsToRemove = new HashSet<String>();
				for (Map.Entry<StringMultiValueMap<StringString>> entry : this..entrySet()) {
					String destination = entry.getKey();
					MultiValueMap<StringStringsessionMap = entry.getValue();
					if (sessionMap.remove(info.getSessionId()) != null) {
						if (sessionMap.isEmpty()) {
							destinationsToRemove.add(destination);
						}
						else {
							this..put(destinationnew LinkedMultiValueMap<StringString>(sessionMap));
						}
					}
				}
				for (String destination : destinationsToRemove) {
					this..remove(destination);
					this..remove(destination);
				}
			}
		}
		public String toString() {
			return "[cache=" + this. + "]";
		}
	}

Provide access to session subscriptions by sessionId.
	private static class SessionSubscriptionRegistry {
		// sessionId -> SessionSubscriptionInfo
			return this..get(sessionId);
		}
			return this..values();
		}
		public SessionSubscriptionInfo addSubscription(String sessionIdString subscriptionIdString destination) {
			SessionSubscriptionInfo info = this..get(sessionId);
			if (info == null) {
				info = new SessionSubscriptionInfo(sessionId);
				SessionSubscriptionInfo value = this..putIfAbsent(sessionIdinfo);
				if (value != null) {
					info = value;
				}
			}
			info.addSubscription(destinationsubscriptionId);
			return info;
		}
			return this..remove(sessionId);
		}
		public String toString() {
			return "[sessions=" +  + "]";
		}
	}

Hold subscriptions for a session.
	private static class SessionSubscriptionInfo {
		private final String sessionId;
		// destination -> subscriptionIds
		private final Map<StringSet<String>> subscriptions = new ConcurrentHashMap<StringSet<String>>(4);
		private final Object monitor = new Object();
		public SessionSubscriptionInfo(String sessionId) {
			Assert.notNull(sessionId"sessionId must not be null");
			this. = sessionId;
		}
		public String getSessionId() {
			return this.;
		}
		public Set<StringgetDestinations() {
			return this..keySet();
		}
		public Set<StringgetSubscriptions(String destination) {
			return this..get(destination);
		}
		public void addSubscription(String destinationString subscriptionId) {
			Set<Stringsubs = this..get(destination);
			if (subs == null) {
				synchronized (this.) {
					subs = this..get(destination);
					if (subs == null) {
						subs = new HashSet<String>(4);
						this..put(destinationsubs);
					}
				}
			}
			subs.add(subscriptionId);
		}
		public String removeSubscription(String subscriptionId) {
			for (String destination : this..keySet()) {
				Set<StringsubscriptionIds = this..get(destination);
				if (subscriptionIds.remove(subscriptionId)) {
					synchronized (this.) {
						if (subscriptionIds.isEmpty()) {
							this..remove(destination);
						}
					}
					return destination;
				}
			}
			return null;
		}
		public String toString() {
			return "[sessionId=" + this. + ", subscriptions=" + this. + "]";
		}
	}
New to GrepCode? Check out our FAQ X