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}