/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.activemq.artemis.core.paging.impl; import java.util.Arrays; import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.ActiveMQBuffers; import org.apache.activemq.artemis.api.core.ICoreMessage; import org.apache.activemq.artemis.api.core.Message; import org.apache.activemq.artemis.core.paging.PagedMessage; import org.apache.activemq.artemis.core.persistence.StorageManager; import org.apache.activemq.artemis.core.persistence.impl.journal.codec.LargeMessagePersister; import org.apache.activemq.artemis.core.server.LargeServerMessage; import org.apache.activemq.artemis.spi.core.protocol.MessagePersister; import org.apache.activemq.artemis.utils.DataConstants; /** * This class represents a paged message */ public class PagedMessageImpl implements PagedMessage { /** * Large messages will need to be instantiated lazily during getMessage when the StorageManager * is available */ private byte[] largeMessageLazyData; private Message message; private long[] queueIDs; private long transactionID = 0; private volatile StorageManager storageManager; public PagedMessageImpl(final Message message, final long[] queueIDs, final long transactionID) { this(message, queueIDs); this.transactionID = transactionID; } public PagedMessageImpl(final Message message, final long[] queueIDs) { this.queueIDs = queueIDs; this.message = message; } public PagedMessageImpl(StorageManager storageManager) { this.storageManager = storageManager; } @Override public Message getMessage() { return message; } @Override public void initMessage(StorageManager storage) { if (largeMessageLazyData != null) { LargeServerMessage lgMessage = storage.createLargeMessage(); ActiveMQBuffer buffer = ActiveMQBuffers.wrappedBuffer(largeMessageLazyData); lgMessage = LargeMessagePersister.getInstance().decode(buffer, lgMessage); lgMessage.incrementDelayDeletionCount(); lgMessage.setPaged(); this.message = lgMessage; largeMessageLazyData = null; } } @Override public long getTransactionID() { return transactionID; } @Override public long[] getQueueIDs() { return queueIDs; } // EncodingSupport implementation -------------------------------- @Override public void decode(final ActiveMQBuffer buffer) { transactionID = buffer.readLong(); boolean isLargeMessage = buffer.readBoolean(); if (isLargeMessage) { int largeMessageHeaderSize = buffer.readInt(); if (storageManager == null) { largeMessageLazyData = new byte[largeMessageHeaderSize]; buffer.readBytes(largeMessageLazyData); } else { this.message = storageManager.createLargeMessage(); LargeMessagePersister.getInstance().decode(buffer, (LargeServerMessage) message); ((LargeServerMessage) message).incrementDelayDeletionCount(); } } else { this.message = MessagePersister.getInstance().decode(buffer, null); } int queueIDsSize = buffer.readInt(); queueIDs = new long[queueIDsSize]; for (int i = 0; i < queueIDsSize; i++) { queueIDs[i] = buffer.readLong(); } } @Override public void encode(final ActiveMQBuffer buffer) { buffer.writeLong(transactionID); boolean isLargeMessage = isLargeMessage(); buffer.writeBoolean(isLargeMessage); if (isLargeMessage) { buffer.writeInt(LargeMessagePersister.getInstance().getEncodeSize((LargeServerMessage)message)); LargeMessagePersister.getInstance().encode(buffer, (LargeServerMessage) message); } else { message.getPersister().encode(buffer, message); } buffer.writeInt(queueIDs.length); for (long queueID : queueIDs) { buffer.writeLong(queueID); } } public boolean isLargeMessage() { return message instanceof ICoreMessage && ((ICoreMessage)message).isLargeMessage(); } @Override public int getEncodeSize() { if (isLargeMessage()) { return DataConstants.SIZE_LONG + DataConstants.SIZE_BYTE + DataConstants.SIZE_INT + LargeMessagePersister.getInstance().getEncodeSize((LargeServerMessage)message) + DataConstants.SIZE_INT + queueIDs.length * DataConstants.SIZE_LONG; } else { return DataConstants.SIZE_LONG + DataConstants.SIZE_BYTE + message.getPersister().getEncodeSize(message) + DataConstants.SIZE_INT + queueIDs.length * DataConstants.SIZE_LONG; } } @Override public String toString() { return "PagedMessageImpl [queueIDs=" + Arrays.toString(queueIDs) + ", transactionID=" + transactionID + ", message=" + message + "]"; } }