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.UnsupportedEncodingException;
020 import java.util.Arrays;
021 import java.util.HashMap;
022 import java.util.Map;
023
024 import org.apache.activemq.command.Command;
025 import org.apache.activemq.command.Endpoint;
026 import org.apache.activemq.command.Response;
027 import org.apache.activemq.state.CommandVisitor;
028 import org.apache.activemq.util.MarshallingSupport;
029
030 /**
031 * Represents all the data in a STOMP frame.
032 *
033 * @author <a href="http://hiramchirino.com">chirino</a>
034 */
035 public class StompFrame implements Command {
036
037 public static final byte[] NO_DATA = new byte[] {};
038
039 private String action;
040 private Map<String, String> headers = new HashMap<String, String>();
041 private byte[] content = NO_DATA;
042
043 public StompFrame(String command) {
044 this(command, null, null);
045 }
046
047 public StompFrame(String command, Map<String, String> headers) {
048 this(command, headers, null);
049 }
050
051 public StompFrame(String command, Map<String, String> headers, byte[] data) {
052 this.action = command;
053 if (headers != null)
054 this.headers = headers;
055 if (data != null)
056 this.content = data;
057 }
058
059 public StompFrame() {
060 }
061
062 public String getAction() {
063 return action;
064 }
065
066 public void setAction(String command) {
067 this.action = command;
068 }
069
070 public byte[] getContent() {
071 return content;
072 }
073
074 public String getBody() {
075 try {
076 return new String(content, "UTF-8");
077 } catch (UnsupportedEncodingException e) {
078 return new String(content);
079 }
080 }
081
082 public void setContent(byte[] data) {
083 this.content = data;
084 }
085
086 public Map<String, String> getHeaders() {
087 return headers;
088 }
089
090 public void setHeaders(Map<String, String> headers) {
091 this.headers = headers;
092 }
093
094 //
095 // Methods in the Command interface
096 //
097 public int getCommandId() {
098 return 0;
099 }
100
101 public Endpoint getFrom() {
102 return null;
103 }
104
105 public Endpoint getTo() {
106 return null;
107 }
108
109 public boolean isBrokerInfo() {
110 return false;
111 }
112
113 public boolean isMessage() {
114 return false;
115 }
116
117 public boolean isMessageAck() {
118 return false;
119 }
120
121 public boolean isMessageDispatch() {
122 return false;
123 }
124
125 public boolean isMessageDispatchNotification() {
126 return false;
127 }
128
129 public boolean isResponse() {
130 return false;
131 }
132
133 public boolean isResponseRequired() {
134 return false;
135 }
136
137 public boolean isShutdownInfo() {
138 return false;
139 }
140
141 public boolean isConnectionControl() {
142 return false;
143 }
144
145 public boolean isWireFormatInfo() {
146 return false;
147 }
148
149 public void setCommandId(int value) {
150 }
151
152 public void setFrom(Endpoint from) {
153 }
154
155 public void setResponseRequired(boolean responseRequired) {
156 }
157
158 public void setTo(Endpoint to) {
159 }
160
161 public Response visit(CommandVisitor visitor) throws Exception {
162 return null;
163 }
164
165 public byte getDataStructureType() {
166 return 0;
167 }
168
169 public boolean isMarshallAware() {
170 return false;
171 }
172
173 public String toString() {
174 return format(true);
175 }
176
177 public String format() {
178 return format(false);
179 }
180
181 public String format(boolean forLogging) {
182 StringBuilder buffer = new StringBuilder();
183 buffer.append(getAction());
184 buffer.append("\n");
185 Map<String, String> headers = getHeaders();
186 for (Map.Entry<String, String> entry : headers.entrySet()) {
187 buffer.append(entry.getKey());
188 buffer.append(":");
189 if (forLogging && entry.getKey().toString().toLowerCase().contains(Stomp.Headers.Connect.PASSCODE)) {
190 buffer.append("*****");
191 } else {
192 buffer.append(entry.getValue());
193 }
194 buffer.append("\n");
195 }
196 buffer.append("\n");
197 if (getContent() != null) {
198 try {
199 String contentString = new String(getContent(), "UTF-8");
200 if (forLogging) {
201 contentString = MarshallingSupport.truncate64(contentString);
202 }
203 buffer.append(contentString);
204 } catch (Throwable e) {
205 buffer.append(Arrays.toString(getContent()));
206 }
207 }
208 // terminate the frame
209 buffer.append('\u0000');
210 return buffer.toString();
211 }
212 }