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     */
017    package org.apache.activemq.transport.stomp;
018    
019    import java.io.IOException;
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    import javax.jms.Destination;
024    import javax.jms.JMSException;
025    
026    import org.apache.activemq.command.ActiveMQBytesMessage;
027    import org.apache.activemq.command.ActiveMQDestination;
028    import org.apache.activemq.command.ActiveMQMessage;
029    import org.apache.activemq.command.ActiveMQTextMessage;
030    
031    /**
032     * Implements ActiveMQ 4.0 translations
033     */
034    public class LegacyFrameTranslator implements FrameTranslator {
035            
036            
037        public ActiveMQMessage convertFrame(ProtocolConverter converter, StompFrame command) throws JMSException, ProtocolException {
038            final Map headers = command.getHeaders();
039            final ActiveMQMessage msg;
040            if (headers.containsKey(Stomp.Headers.CONTENT_LENGTH)) {
041                headers.remove(Stomp.Headers.CONTENT_LENGTH);
042                ActiveMQBytesMessage bm = new ActiveMQBytesMessage();
043                bm.writeBytes(command.getContent());
044                msg = bm;
045            } else {
046                ActiveMQTextMessage text = new ActiveMQTextMessage();
047                try {
048                    text.setText(new String(command.getContent(), "UTF-8"));
049                } catch (Throwable e) {
050                    throw new ProtocolException("Text could not bet set: " + e, false, e);
051                }
052                msg = text;
053            }
054            FrameTranslator.Helper.copyStandardHeadersFromFrameToMessage(converter, command, msg, this);
055            return msg;
056        }
057    
058        public StompFrame convertMessage(ProtocolConverter converter, ActiveMQMessage message) throws IOException, JMSException {
059            StompFrame command = new StompFrame();
060            command.setAction(Stomp.Responses.MESSAGE);
061            Map<String, String> headers = new HashMap<String, String>(25);
062            command.setHeaders(headers);
063    
064            FrameTranslator.Helper.copyStandardHeadersFromMessageToFrame(converter, message, command, this);
065    
066            if (message.getDataStructureType() == ActiveMQTextMessage.DATA_STRUCTURE_TYPE) {
067    
068                ActiveMQTextMessage msg = (ActiveMQTextMessage)message.copy();
069                command.setContent(msg.getText().getBytes("UTF-8"));
070    
071            } else if (message.getDataStructureType() == ActiveMQBytesMessage.DATA_STRUCTURE_TYPE) {
072    
073                ActiveMQBytesMessage msg = (ActiveMQBytesMessage)message.copy();
074                msg.setReadOnlyBody(true);
075                byte[] data = new byte[(int)msg.getBodyLength()];
076                msg.readBytes(data);
077    
078                headers.put(Stomp.Headers.CONTENT_LENGTH, "" + data.length);
079                command.setContent(data);
080            }
081            return command;
082        }
083    
084        public String convertDestination(ProtocolConverter converter, Destination d) {
085            if (d == null) {
086                return null;
087            }
088            ActiveMQDestination activeMQDestination = (ActiveMQDestination)d;
089            String physicalName = activeMQDestination.getPhysicalName();
090    
091            String rc = converter.getCreatedTempDestinationName(activeMQDestination);
092            if( rc!=null ) {
093                    return rc;
094            }
095            
096            StringBuffer buffer = new StringBuffer();
097            if (activeMQDestination.isQueue()) {
098                if (activeMQDestination.isTemporary()) {
099                    buffer.append("/remote-temp-queue/");
100                } else {
101                    buffer.append("/queue/");
102                }
103            } else {
104                if (activeMQDestination.isTemporary()) {
105                    buffer.append("/remote-temp-topic/");
106                } else {
107                    buffer.append("/topic/");
108                }
109            }
110            buffer.append(physicalName);
111            return buffer.toString();
112        }
113    
114        public ActiveMQDestination convertDestination(ProtocolConverter converter, String name) throws ProtocolException {
115            if (name == null) {
116                return null;
117            } else if (name.startsWith("/queue/")) {
118                String qName = name.substring("/queue/".length(), name.length());
119                return ActiveMQDestination.createDestination(qName, ActiveMQDestination.QUEUE_TYPE);
120            } else if (name.startsWith("/topic/")) {
121                String tName = name.substring("/topic/".length(), name.length());
122                return ActiveMQDestination.createDestination(tName, ActiveMQDestination.TOPIC_TYPE);
123            } else if (name.startsWith("/remote-temp-queue/")) {
124                String tName = name.substring("/remote-temp-queue/".length(), name.length());
125                return ActiveMQDestination.createDestination(tName, ActiveMQDestination.TEMP_QUEUE_TYPE);
126            } else if (name.startsWith("/remote-temp-topic/")) {
127                String tName = name.substring("/remote-temp-topic/".length(), name.length());
128                return ActiveMQDestination.createDestination(tName, ActiveMQDestination.TEMP_TOPIC_TYPE);
129            } else if (name.startsWith("/temp-queue/")) {
130                return converter.createTempQueue(name);
131            } else if (name.startsWith("/temp-topic/")) {
132                return converter.createTempTopic(name);
133            } else {
134                throw new ProtocolException("Illegal destination name: [" + name + "] -- ActiveMQ STOMP destinations "
135                                            + "must begine with one of: /queue/ /topic/ /temp-queue/ /temp-topic/");
136            }
137        }
138    }