/* * Copyright 2014-2017 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.integration.support; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.springframework.integration.IntegrationMessageHeaderAccessor; import org.springframework.messaging.Message; import org.springframework.util.Assert; import org.springframework.util.PatternMatchUtils; import org.springframework.util.StringUtils; /** * @author Gary Russell * @author Artem Bilan * @since 4.0 * */ public final class MutableMessageBuilder<T> extends AbstractIntegrationMessageBuilder<T> { private final MutableMessage<T> mutableMessage; private final Map<String, Object> headers; /** * Private constructor to be invoked from the static factory methods only. */ private MutableMessageBuilder(Message<T> message) { Assert.notNull(message, "message must not be null"); if (message instanceof MutableMessage) { this.mutableMessage = (MutableMessage<T>) message; } else { this.mutableMessage = new MutableMessage<T>(message.getPayload(), message.getHeaders()); } this.headers = this.mutableMessage.getRawHeaders(); } @Override public T getPayload() { return this.mutableMessage.getPayload(); } @Override public Map<String, Object> getHeaders() { return this.headers; } /** * Create a builder for a new {@link Message} instance pre-populated with all of the headers copied from the * provided message. The payload of the provided Message will also be used as the payload for the new message. * @param message the Message from which the payload and all headers will be copied * @param <T> The type of the payload. * @return A MutableMessageBuilder. */ public static <T> MutableMessageBuilder<T> fromMessage(Message<T> message) { Assert.notNull(message, "'message' must not be null"); return new MutableMessageBuilder<T>(message); } /** * Create a builder for a new {@link Message} instance with the provided payload. * @param payload the payload for the new message * @param <T> The type of the payload. * @return A MessageBuilder. */ public static <T> MutableMessageBuilder<T> withPayload(T payload) { return new MutableMessageBuilder<T>(new MutableMessage<T>(payload)); } @Override public AbstractIntegrationMessageBuilder<T> setHeader(String headerName, Object headerValue) { Assert.notNull(headerName, "'headerName' must not be null"); if (headerValue == null) { this.removeHeader(headerName); } else { this.headers.put(headerName, headerValue); } return this; } @Override public AbstractIntegrationMessageBuilder<T> setHeaderIfAbsent(String headerName, Object headerValue) { if (!this.headers.containsKey(headerName)) { this.headers.put(headerName, headerValue); } return this; } @Override public AbstractIntegrationMessageBuilder<T> removeHeaders(String... headerPatterns) { List<String> headersToRemove = new ArrayList<String>(); for (String pattern : headerPatterns) { if (StringUtils.hasLength(pattern)) { if (pattern.contains("*")) { headersToRemove.addAll(getMatchingHeaderNames(pattern, this.headers)); } else { headersToRemove.add(pattern); } } } for (String headerToRemove : headersToRemove) { removeHeader(headerToRemove); } return this; } private List<String> getMatchingHeaderNames(String pattern, Map<String, Object> headers) { List<String> matchingHeaderNames = new ArrayList<String>(); if (headers != null) { for (Map.Entry<String, Object> header : headers.entrySet()) { if (PatternMatchUtils.simpleMatch(pattern, header.getKey())) { matchingHeaderNames.add(header.getKey()); } } } return matchingHeaderNames; } @Override public AbstractIntegrationMessageBuilder<T> removeHeader(String headerName) { if (StringUtils.hasLength(headerName)) { this.headers.remove(headerName); } return this; } @Override public AbstractIntegrationMessageBuilder<T> copyHeaders(Map<String, ?> headersToCopy) { if (headersToCopy != null) { this.headers.putAll(headersToCopy); } return this; } @Override public AbstractIntegrationMessageBuilder<T> copyHeadersIfAbsent(Map<String, ?> headersToCopy) { if (headersToCopy != null) { for (Entry<String, ?> entry : headersToCopy.entrySet()) { setHeaderIfAbsent(entry.getKey(), entry.getValue()); } } return this; } @SuppressWarnings("unchecked") @Override protected List<List<Object>> getSequenceDetails() { return (List<List<Object>>) this.headers.get(IntegrationMessageHeaderAccessor.SEQUENCE_DETAILS); } @Override protected Object getCorrelationId() { return this.headers.get(IntegrationMessageHeaderAccessor.CORRELATION_ID); } @Override protected Object getSequenceNumber() { return this.headers.get(IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER); } @Override protected Object getSequenceSize() { return this.headers.get(IntegrationMessageHeaderAccessor.SEQUENCE_SIZE); } @Override public Message<T> build() { return this.mutableMessage; } }