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