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 027public abstract class CompositeDestination implements VirtualDestination { 028 029 private String name; 030 private Collection forwardTo; 031 private boolean forwardOnly = true; 032 private boolean concurrentSend = false; 033 private boolean sendWhenNotMatched = false; 034 035 @Override 036 public Destination intercept(Destination destination) { 037 return new CompositeDestinationFilter(destination, getForwardTo(), isForwardOnly(),isSendWhenNotMatched(), isConcurrentSend()); 038 } 039 040 @Override 041 public void create(Broker broker, ConnectionContext context, ActiveMQDestination destination) { 042 } 043 044 @Override 045 public void remove(Destination destination) { 046 } 047 048 public String getName() { 049 return name; 050 } 051 052 /** 053 * Sets the name of this composite destination 054 */ 055 public void setName(String name) { 056 this.name = name; 057 } 058 059 public Collection getForwardTo() { 060 return forwardTo; 061 } 062 063 /** 064 * Sets the list of destinations to forward to 065 */ 066 public void setForwardTo(Collection forwardDestinations) { 067 this.forwardTo = forwardDestinations; 068 } 069 070 public boolean isForwardOnly() { 071 return forwardOnly; 072 } 073 074 /** 075 * Sets if the virtual destination is forward only (and so there is no 076 * physical queue to match the virtual queue) or if there is also a physical 077 * queue with the same name). 078 */ 079 public void setForwardOnly(boolean forwardOnly) { 080 this.forwardOnly = forwardOnly; 081 } 082 083 @Deprecated 084 public boolean isCopyMessage() { 085 return true; 086 } 087 088 /** 089 * Sets whether a copy of the message will be sent to each destination. 090 * Defaults to true so that the forward destination is set as the 091 * destination of the message 092 * 093 * @deprecated this option will be removed in a later release, message are always copied. 094 */ 095 @Deprecated 096 public void setCopyMessage(boolean copyMessage) { 097 } 098 099 /** 100 * when true, sends are done in parallel with the broker executor 101 */ 102 public void setConcurrentSend(boolean concurrentSend) { 103 this.concurrentSend = concurrentSend; 104 } 105 106 public boolean isConcurrentSend() { 107 return this.concurrentSend; 108 } 109 110 @Override 111 public ActiveMQDestination getMappedDestinations() { 112 final ActiveMQDestination[] destinations = new ActiveMQDestination[forwardTo.size()]; 113 int i = 0; 114 for (Object dest : forwardTo) { 115 if (dest instanceof FilteredDestination) { 116 FilteredDestination filteredDestination = (FilteredDestination) dest; 117 destinations[i++] = filteredDestination.getDestination(); 118 } else if (dest instanceof ActiveMQDestination) { 119 destinations[i++] = (ActiveMQDestination) dest; 120 } else { 121 // highly unlikely, but just in case! 122 throw new IllegalArgumentException("Unknown mapped destination type " + dest); 123 } 124 } 125 126 // used just for matching destination paths 127 return new ActiveMQDestination(destinations) { 128 @Override 129 protected String getQualifiedPrefix() { 130 return "mapped://"; 131 } 132 133 @Override 134 public byte getDestinationType() { 135 return QUEUE_TYPE | TOPIC_TYPE; 136 } 137 138 @Override 139 public byte getDataStructureType() { 140 return CommandTypes.ACTIVEMQ_QUEUE | CommandTypes.ACTIVEMQ_TOPIC; 141 } 142 }; 143 } 144 145 @Override 146 public int hashCode() { 147 final int prime = 31; 148 int result = 1; 149 result = prime * result + (concurrentSend ? 1231 : 1237); 150 result = prime * result + (forwardOnly ? 1231 : 1237); 151 result = prime * result + ((forwardTo == null) ? 0 : forwardTo.hashCode()); 152 result = prime * result + ((name == null) ? 0 : name.hashCode()); 153 return result; 154 } 155 156 @Override 157 public boolean equals(Object obj) { 158 if (this == obj) { 159 return true; 160 } 161 162 if (obj == null) { 163 return false; 164 } 165 166 if (getClass() != obj.getClass()) { 167 return false; 168 } 169 170 CompositeDestination other = (CompositeDestination) obj; 171 if (concurrentSend != other.concurrentSend) { 172 return false; 173 } 174 175 if (forwardOnly != other.forwardOnly) { 176 return false; 177 } 178 179 if (forwardTo == null) { 180 if (other.forwardTo != null) { 181 return false; 182 } 183 } else if (!forwardTo.equals(other.forwardTo)) { 184 return false; 185 } 186 187 if (name == null) { 188 if (other.name != null) 189 return false; 190 } else if (!name.equals(other.name)) { 191 return false; 192 } 193 194 return true; 195 } 196 197 public boolean isSendWhenNotMatched() { 198 return sendWhenNotMatched; 199 } 200 201 public void setSendWhenNotMatched(boolean sendWhenNotMatched) { 202 this.sendWhenNotMatched = sendWhenNotMatched; 203 } 204}