private MultiValueMap<String, String> getCookies() { if (this.cookies == null) { this.cookies = new LinkedMultiValueMap<>(4); } return this.cookies; }
public LinkedMultiValueMap<String, String> getSubscriptions(String destination, Message<?> message) { LinkedMultiValueMap<String, String> result = this.accessCache.get(destination); if (result == null) { synchronized (this.updateCache) { result = new LinkedMultiValueMap<>(); for (SessionSubscriptionInfo info : subscriptionRegistry.getAllSubscriptions()) { for (String destinationPattern : info.getDestinations()) { if (getPathMatcher().match(destinationPattern, destination)) { for (Subscription sub : info.getSubscriptions(destinationPattern)) { result.add(info.sessionId, sub.getId()); } } } } if (!result.isEmpty()) { this.updateCache.put(destination, result.deepCopy()); this.accessCache.put(destination, result); } } } return result; }
@Override @Nullable public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) { if (!this.attributesMap.containsKey(annotationName)) { return null; } MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<>(); List<AnnotationAttributes> attributesList = this.attributesMap.get(annotationName); if (attributesList != null) { for (AnnotationAttributes annotationAttributes : attributesList) { AnnotationAttributes convertedAttributes = AnnotationReadingVisitorUtils.convertClassValues( "method '" + getMethodName() + "'", this.classLoader, annotationAttributes, classValuesAsString); convertedAttributes.forEach(allAttributes::add); } } return allAttributes; }
/** * Create a deep copy of this Map. * @return a copy of this Map, including a copy of each value-holding List entry * (consistently using an independent modifiable {@link LinkedList} for each entry) * along the lines of {@code MultiValueMap.addAll} semantics * @since 4.2 * @see #addAll(MultiValueMap) * @see #clone() */ public LinkedMultiValueMap<K, V> deepCopy() { LinkedMultiValueMap<K, V> copy = new LinkedMultiValueMap<>(this.targetMap.size()); this.targetMap.forEach((key, value) -> copy.put(key, new LinkedList<>(value))); return copy; }
/** * Return a {@code MultiValueMap} with the configured parts. */ public MultiValueMap<String, HttpEntity<?>> build() { MultiValueMap<String, HttpEntity<?>> result = new LinkedMultiValueMap<>(this.parts.size()); for (Map.Entry<String, List<DefaultPartBuilder>> entry : this.parts.entrySet()) { for (DefaultPartBuilder builder : entry.getValue()) { HttpEntity<?> entity = builder.build(); result.add(entry.getKey(), entity); } } return result; }
public void updateAfterNewSubscription(String destination, String sessionId, String subsId) { synchronized (this.updateCache) { this.updateCache.forEach((cachedDestination, subscriptions) -> { if (getPathMatcher().match(destination, cachedDestination)) { // Subscription id's may also be populated via getSubscriptions() List<String> subsForSession = subscriptions.get(sessionId); if (subsForSession == null || !subsForSession.contains(subsId)) { subscriptions.add(sessionId, subsId); this.accessCache.put(cachedDestination, subscriptions.deepCopy()); } } }); } }
@Override @Nullable public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) { MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<>(); List<AnnotationAttributes> attributes = this.attributesMap.get(annotationName); if (attributes == null) { return null; } for (AnnotationAttributes raw : attributes) { for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues( "class '" + getClassName() + "'", this.classLoader, raw, classValuesAsString).entrySet()) { allAttributes.add(entry.getKey(), entry.getValue()); } } return allAttributes; }
@Test public void pathSegmentParams() throws Exception { // basic LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("colors", "red"); params.add("colors", "blue"); params.add("colors", "green"); params.add("year", "2012"); testPathSegment("cars;colors=red,blue,green;year=2012", "cars", params); // trailing semicolon params = new LinkedMultiValueMap<>(); params.add("p", "1"); testPathSegment("path;p=1;", "path", params); // params with spaces params = new LinkedMultiValueMap<>(); params.add("param name", "param value"); testPathSegment("path;param%20name=param%20value;%20", "path", params); // empty params params = new LinkedMultiValueMap<>(); params.add("p", "1"); testPathSegment("path;;;%20;%20;p=1;%20", "path", params); }
@Test public void equals() { map.set("key1", "value1"); assertEquals(map, map); MultiValueMap<String, String> o1 = new LinkedMultiValueMap<>(); o1.set("key1", "value1"); assertEquals(map, o1); assertEquals(o1, map); Map<String, List<String>> o2 = new HashMap<>(); o2.put("key1", Collections.singletonList("value1")); assertEquals(map, o2); assertEquals(o2, map); }
@Test public void addAll() throws Exception { map.add("key", "value1"); map.addAll("key", Arrays.asList("value2", "value3")); assertEquals(1, map.size()); List<String> expected = new ArrayList<>(2); expected.add("value1"); expected.add("value2"); expected.add("value3"); assertEquals(expected, map.get("key")); }
/** * Add an asynchronous part with {@link Publisher}-based content. * @param name the name of the part to add * @param publisher the part contents * @param elementClass the type of elements contained in the publisher * @return builder that allows for further customization of part headers */ public <T, P extends Publisher<T>> PartBuilder asyncPart(String name, P publisher, Class<T> elementClass) { Assert.hasLength(name, "'name' must not be empty"); Assert.notNull(publisher, "'publisher' must not be null"); Assert.notNull(elementClass, "'elementClass' must not be null"); HttpHeaders headers = new HttpHeaders(); PublisherPartBuilder<T, P> builder = new PublisherPartBuilder<>(headers, publisher, elementClass); this.parts.add(name, builder); return builder; }
public void updateAfterRemovedSubscription(String sessionId, String subsId) { synchronized (this.updateCache) { Set<String> destinationsToRemove = new HashSet<>(); this.updateCache.forEach((destination, sessionMap) -> { List<String> subscriptions = sessionMap.get(sessionId); if (subscriptions != null) { subscriptions.remove(subsId); if (subscriptions.isEmpty()) { sessionMap.remove(sessionId); } if (sessionMap.isEmpty()) { destinationsToRemove.add(destination); } else { this.accessCache.put(destination, sessionMap.deepCopy()); } } }); for (String destination : destinationsToRemove) { this.updateCache.remove(destination); this.accessCache.remove(destination); } } }
/** * Variant of {@link #asyncPart(String, Publisher, Class)} that accepts a * {@link ParameterizedTypeReference} for the element type, which allows * specifying generic type information. * @param name the name of the part to add * @param publisher the part contents * @param typeReference the type of elements contained in the publisher * @return builder that allows for further customization of part headers */ public <T, P extends Publisher<T>> PartBuilder asyncPart( String name, P publisher, ParameterizedTypeReference<T> typeReference) { Assert.hasLength(name, "'name' must not be empty"); Assert.notNull(publisher, "'publisher' must not be null"); Assert.notNull(typeReference, "'typeReference' must not be null"); HttpHeaders headers = new HttpHeaders(); PublisherPartBuilder<T, P> builder = new PublisherPartBuilder<>(headers, publisher, typeReference); this.parts.add(name, builder); return builder; }
/** * Create a new instance to be populated with new header values. */ public StompHeaders() { this(new LinkedMultiValueMap<>(4), false); }
private MultiValueMap<String, String> initCookies() { if (this.defaultCookies == null) { this.defaultCookies = new LinkedMultiValueMap<>(4); } return this.defaultCookies; }
@Override public MultiValueMap<String, MultipartFile> getMultiFileMap() { return new LinkedMultiValueMap<>(this.multipartFiles); }
@Override protected MultiValueMap<HttpRequestHandler, String> createMappings() { return new LinkedMultiValueMap<>(); }
/** * Create a regular copy of this Map. * @return a shallow copy of this Map, reusing this Map's value-holding List entries * (even if some entries are shared or unmodifiable) along the lines of standard * {@code Map.put} semantics * @since 4.2 * @see #put(Object, List) * @see #putAll(Map) * @see LinkedMultiValueMap#LinkedMultiValueMap(Map) * @see #deepCopy() */ @Override public LinkedMultiValueMap<K, V> clone() { return new LinkedMultiValueMap<>(this); }