/*
* 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.tests.integration.stomp.util;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.activemq.artemis.core.protocol.stomp.Stomp;
public abstract class AbstractClientStompFrame implements ClientStompFrame {
protected static final Set<String> validCommands = new HashSet<>();
protected String command;
protected List<Header> headers = new ArrayList<>();
protected Set<String> headerKeys = new HashSet<>();
protected String body;
protected String EOL = "\n";
static {
validCommands.add(Stomp.Commands.CONNECT);
validCommands.add(Stomp.Responses.CONNECTED);
validCommands.add(Stomp.Commands.SEND);
validCommands.add(Stomp.Responses.RECEIPT);
validCommands.add(Stomp.Commands.SUBSCRIBE);
validCommands.add(Stomp.Commands.UNSUBSCRIBE);
validCommands.add(Stomp.Responses.MESSAGE);
validCommands.add(Stomp.Commands.BEGIN);
validCommands.add(Stomp.Commands.COMMIT);
validCommands.add(Stomp.Commands.ABORT);
validCommands.add(Stomp.Commands.ACK);
validCommands.add(Stomp.Commands.DISCONNECT);
validCommands.add(Stomp.Responses.ERROR);
}
public AbstractClientStompFrame(String command) {
this(command, true);
}
public AbstractClientStompFrame(String command, boolean validate) {
if (validate && (!validate(command)))
throw new IllegalArgumentException("Invalid command " + command);
this.command = command;
}
public boolean validate(String command) {
return validCommands.contains(command);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer("Frame: <" + command + ">" + "\n");
Iterator<Header> iter = headers.iterator();
while (iter.hasNext()) {
Header h = iter.next();
sb.append(h.key + ":" + h.val + "\n");
}
sb.append("\n");
sb.append("<body>" + body + "<body>");
return sb.toString();
}
@Override
public ByteBuffer toByteBuffer() {
return toByteBufferInternal(null);
}
@Override
public ByteBuffer toByteBufferWithExtra(String str) {
return toByteBufferInternal(str);
}
public ByteBuffer toByteBufferInternal(String str) {
StringBuffer sb = new StringBuffer();
sb.append(command + EOL);
int n = headers.size();
for (int i = 0; i < n; i++) {
sb.append(headers.get(i).key + ":" + headers.get(i).val + EOL);
}
sb.append(EOL);
if (body != null) {
sb.append(body);
}
sb.append((char) 0);
if (str != null) {
sb.append(str);
}
String data = sb.toString();
byte[] byteValue = data.getBytes(StandardCharsets.UTF_8);
ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
buffer.put(byteValue);
buffer.rewind();
return buffer;
}
@Override
public boolean needsReply() {
if (Stomp.Commands.CONNECT.equals(command) || headerKeys.contains(Stomp.Headers.RECEIPT_REQUESTED)) {
return true;
}
return false;
}
@Override
public ClientStompFrame setCommand(String command) {
this.command = command;
return this;
}
@Override
public ClientStompFrame addHeader(String key, String val) {
headers.add(new Header(key, val));
headerKeys.add(key);
return this;
}
@Override
public ClientStompFrame setBody(String body) {
this.body = body;
return this;
}
@Override
public String getBody() {
return body;
}
private class Header {
public String key;
public String val;
private Header(String key, String val) {
this.key = key;
this.val = val;
}
}
@Override
public String getCommand() {
return command;
}
@Override
public String getHeader(String header) {
if (headerKeys.contains(header)) {
Iterator<Header> iter = headers.iterator();
while (iter.hasNext()) {
Header h = iter.next();
if (h.key.equals(header)) {
return h.val;
}
}
}
return null;
}
}