content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements. See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License. You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.activemq.artemis.jms.client.compatible1X;
  
  import javax.jms.Destination;
  import javax.jms.InvalidDestinationException;
  import javax.jms.JMSException;
  import javax.jms.JMSRuntimeException;
  import javax.jms.Message;
  
  import org.apache.activemq.artemis.api.core.SimpleString;
  import org.apache.activemq.artemis.api.core.client.ClientMessage;
  import org.apache.activemq.artemis.api.core.client.ClientSession;
  import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl;
  import org.apache.activemq.artemis.jms.client.ActiveMQBytesMessage;
  import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
  import org.apache.activemq.artemis.jms.client.ActiveMQMapMessage;
  import org.apache.activemq.artemis.jms.client.ActiveMQMessage;
  import org.apache.activemq.artemis.jms.client.ActiveMQObjectMessage;
  import org.apache.activemq.artemis.jms.client.ActiveMQStreamMessage;
  import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage;
  import org.apache.activemq.artemis.jms.client.ConnectionFactoryOptions;
  import org.apache.activemq.artemis.reader.MessageUtil;
  
  public class ActiveMQCompatibleMessage extends ActiveMQMessage {
  
     public ActiveMQCompatibleMessage(byte type, ClientSession session) {
        super(type, session);
     }
  
     public ActiveMQCompatibleMessage(ClientSession session) {
        super(session);
     }
  
     public ActiveMQCompatibleMessage(ClientMessage message, ClientSession session) {
        super(message, session);
     }
  
     public ActiveMQCompatibleMessage(Message foreign, ClientSession session) throws JMSException {
        super(foreign, session);
     }
  
     public ActiveMQCompatibleMessage() {
     }
  
     public ActiveMQCompatibleMessage(Message foreign, byte type, ClientSession session) throws JMSException {
        super(foreign, type, session);
     }
  
     @Override
     public Destination getJMSReplyTo() throws JMSException {
        if (replyTo == null) {
           replyTo = findCompatibleReplyTo(message);
        }
        return replyTo;
     }
  
     @Override
     public void setJMSReplyTo(Destination dest) throws JMSException {
        replyTo = setCompatibleReplyTo(dest, message);
     }
  
     static Destination setCompatibleReplyTo(Destination dest, ClientMessage message) throws InvalidDestinationException {
        if (dest == null) {
           MessageUtil.setJMSReplyTo(message, (String) null);
           return null;
        } else {
           if (dest instanceof ActiveMQDestination == false) {
              throw new InvalidDestinationException("Foreign destination " + dest);
           }
           ActiveMQDestination jbd = (ActiveMQDestination) dest;
           final String address = jbd.getAddress();
           if (hasPrefix1X(address)) {
              MessageUtil.setJMSReplyTo(message, jbd.getAddress());
           } else {
              String prefix = prefixOf(dest);
              MessageUtil.setJMSReplyTo(message, prefix + jbd.getAddress());
           }
           return jbd;
        }
     }
  
     static Destination findCompatibleReplyTo(ClientMessage message) {
        SimpleString address = MessageUtil.getJMSReplyTo(message);
        if (address != null) {
           final SimpleString checkedAddress = checkPrefix1X(address);
           if (checkedAddress != null) {
              return ActiveMQDestination.fromPrefixed1XName(address.toString(), checkedAddress.toString());
           }
           String name = address.toString();
           // swap the old prefixes for the new ones so the proper destination type gets created
           if (address.startsWith(OLD_QUEUE_QUALIFIED_PREFIX)) {
              name = address.subSeq(OLD_QUEUE_QUALIFIED_PREFIX.length(), address.length()).toString();
           } else if (address.startsWith(OLD_TEMP_QUEUE_QUALIFED_PREFIX)) {
              name = address.subSeq(OLD_TEMP_QUEUE_QUALIFED_PREFIX.length(), address.length()).toString();
           } else if (address.startsWith(OLD_TOPIC_QUALIFIED_PREFIX)) {
              name = address.subSeq(OLD_TOPIC_QUALIFIED_PREFIX.length(), address.length()).toString();
           } else if (address.startsWith(OLD_TEMP_TOPIC_QUALIFED_PREFIX)) {
              name = address.subSeq(OLD_TEMP_TOPIC_QUALIFED_PREFIX.length(), address.length()).toString();
           }
           return ActiveMQDestination.fromPrefixedName(address.toString(), name);
        }
  
        return null;
     }
  
     @Override
     public SimpleString checkPrefix(SimpleString address) {
        return checkPrefix1X(address);
     }
  
     private static boolean hasPrefix1X(String address) {
        if (address != null) {
           if (address.startsWith(PacketImpl.OLD_QUEUE_PREFIX.toString())) {
              return true;
           } else if (address.startsWith(PacketImpl.OLD_TEMP_QUEUE_PREFIX.toString())) {
              return true;
           } else if (address.startsWith(PacketImpl.OLD_TOPIC_PREFIX.toString())) {
              return true;
           } else if (address.startsWith(PacketImpl.OLD_TEMP_TOPIC_PREFIX.toString())) {
              return true;
           }
        }
  
        return false;
     }
  
     protected static SimpleString checkPrefix1X(SimpleString address) {
        if (address != null) {
           if (address.startsWith(PacketImpl.OLD_QUEUE_PREFIX)) {
              return address.subSeq(PacketImpl.OLD_QUEUE_PREFIX.length(), address.length());
           } else if (address.startsWith(PacketImpl.OLD_TEMP_QUEUE_PREFIX)) {
              return address.subSeq(PacketImpl.OLD_TEMP_QUEUE_PREFIX.length(), address.length());
           } else if (address.startsWith(PacketImpl.OLD_TOPIC_PREFIX)) {
              return address.subSeq(PacketImpl.OLD_TOPIC_PREFIX.length(), address.length());
           } else if (address.startsWith(PacketImpl.OLD_TEMP_TOPIC_PREFIX)) {
              return address.subSeq(PacketImpl.OLD_TEMP_TOPIC_PREFIX.length(), address.length());
           }
        }
  
        return null;
     }
  
     public static ActiveMQMessage createMessage(final ClientMessage message,
                                                 final ClientSession session,
                                                 final ConnectionFactoryOptions options) {
        int type = message.getType();
  
        ActiveMQMessage msg;
  
        switch (type) {
           case ActiveMQMessage.TYPE: { // 0
              msg = new ActiveMQCompatibleMessage(message, session);
              break;
           }
           case ActiveMQBytesMessage.TYPE: { // 4
              msg = new ActiveMQBytesCompatibleMessage(message, session);
              break;
           }
           case ActiveMQMapMessage.TYPE: { // 5
              msg = new ActiveMQMapCompatibleMessage(message, session);
              break;
           }
           case ActiveMQObjectMessage.TYPE: {
              msg = new ActiveMQObjectCompatibleMessage(message, session, options);
              break;
           }
           case ActiveMQStreamMessage.TYPE: { // 6
              msg = new ActiveMQStreamCompatibleMessage(message, session);
              break;
           }
           case ActiveMQTextMessage.TYPE: { // 3
              msg = new ActiveMQTextCompatibleMessage(message, session);
              break;
           }
           default: {
              throw new JMSRuntimeException("Invalid message type " + type);
           }
        }
  
        return msg;
     }
  
  }
  