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