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    }