001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.broker.region.virtual; 018 019import java.util.Collection; 020 021import org.apache.activemq.broker.Broker; 022import org.apache.activemq.broker.ConnectionContext; 023import org.apache.activemq.broker.region.Destination; 024import org.apache.activemq.command.ActiveMQDestination; 025import org.apache.activemq.command.CommandTypes; 026 027/** 028 * 029 * 030 */ 031public abstract class CompositeDestination implements VirtualDestination { 032 033 private String name; 034 private Collection forwardTo; 035 private boolean forwardOnly = true; 036 private boolean copyMessage = true; 037 private boolean concurrentSend = false; 038 039 @Override 040 public Destination intercept(Destination destination) { 041 return new CompositeDestinationFilter(destination, getForwardTo(), isForwardOnly(), isCopyMessage(), isConcurrentSend()); 042 } 043 044 @Override 045 public void create(Broker broker, ConnectionContext context, ActiveMQDestination destination) { 046 } 047 048 @Override 049 public void remove(Destination destination) { 050 } 051 052 public String getName() { 053 return name; 054 } 055 056 /** 057 * Sets the name of this composite destination 058 */ 059 public void setName(String name) { 060 this.name = name; 061 } 062 063 public Collection getForwardTo() { 064 return forwardTo; 065 } 066 067 /** 068 * Sets the list of destinations to forward to 069 */ 070 public void setForwardTo(Collection forwardDestinations) { 071 this.forwardTo = forwardDestinations; 072 } 073 074 public boolean isForwardOnly() { 075 return forwardOnly; 076 } 077 078 /** 079 * Sets if the virtual destination is forward only (and so there is no 080 * physical queue to match the virtual queue) or if there is also a physical 081 * queue with the same name). 082 */ 083 public void setForwardOnly(boolean forwardOnly) { 084 this.forwardOnly = forwardOnly; 085 } 086 087 public boolean isCopyMessage() { 088 return copyMessage; 089 } 090 091 /** 092 * Sets whether a copy of the message will be sent to each destination. 093 * Defaults to true so that the forward destination is set as the 094 * destination of the message 095 */ 096 public void setCopyMessage(boolean copyMessage) { 097 this.copyMessage = copyMessage; 098 } 099 100 /** 101 * when true, sends are done in parallel with the broker executor 102 */ 103 public void setConcurrentSend(boolean concurrentSend) { 104 this.concurrentSend = concurrentSend; 105 } 106 107 public boolean isConcurrentSend() { 108 return this.concurrentSend; 109 } 110 111 @Override 112 public ActiveMQDestination getMappedDestinations() { 113 114 final ActiveMQDestination[] destinations = new ActiveMQDestination[forwardTo.size()]; 115 int i = 0; 116 for (Object dest : forwardTo) { 117 if (dest instanceof FilteredDestination) { 118 FilteredDestination filteredDestination = (FilteredDestination) dest; 119 destinations[i++] = filteredDestination.getDestination(); 120 } else if (dest instanceof ActiveMQDestination) { 121 destinations[i++] = (ActiveMQDestination) dest; 122 } else { 123 // highly unlikely, but just in case! 124 throw new IllegalArgumentException("Unknown mapped destination type " + dest); 125 } 126 } 127 128 // used just for matching destination paths 129 return new ActiveMQDestination(destinations) { 130 @Override 131 protected String getQualifiedPrefix() { 132 return "mapped://"; 133 } 134 135 @Override 136 public byte getDestinationType() { 137 return QUEUE_TYPE | TOPIC_TYPE; 138 } 139 140 @Override 141 public byte getDataStructureType() { 142 return CommandTypes.ACTIVEMQ_QUEUE | CommandTypes.ACTIVEMQ_TOPIC; 143 } 144 }; 145 } 146 147 @Override 148 public int hashCode() { 149 final int prime = 31; 150 int result = 1; 151 result = prime * result + (concurrentSend ? 1231 : 1237); 152 result = prime * result + (copyMessage ? 1231 : 1237); 153 result = prime * result + (forwardOnly ? 1231 : 1237); 154 result = prime * result 155 + ((forwardTo == null) ? 0 : forwardTo.hashCode()); 156 result = prime * result + ((name == null) ? 0 : name.hashCode()); 157 return result; 158 } 159 160 @Override 161 public boolean equals(Object obj) { 162 if (this == obj) 163 return true; 164 if (obj == null) 165 return false; 166 if (getClass() != obj.getClass()) 167 return false; 168 CompositeDestination other = (CompositeDestination) obj; 169 if (concurrentSend != other.concurrentSend) 170 return false; 171 if (copyMessage != other.copyMessage) 172 return false; 173 if (forwardOnly != other.forwardOnly) 174 return false; 175 if (forwardTo == null) { 176 if (other.forwardTo != null) 177 return false; 178 } else if (!forwardTo.equals(other.forwardTo)) 179 return false; 180 if (name == null) { 181 if (other.name != null) 182 return false; 183 } else if (!name.equals(other.name)) 184 return false; 185 return true; 186 } 187}