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.Locale;
023    import java.util.Map;
024    
025    import org.apache.activemq.command.Command;
026    import org.apache.activemq.command.Endpoint;
027    import org.apache.activemq.command.Response;
028    import org.apache.activemq.state.CommandVisitor;
029    import 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     */
036    public 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            StringBuilder buffer = new StringBuilder();
184            buffer.append(getAction());
185            buffer.append("\n");
186            Map<String, String> headers = getHeaders();
187            for (Map.Entry<String, String> entry : headers.entrySet()) {
188                buffer.append(entry.getKey());
189                buffer.append(":");
190                if (forLogging && entry.getKey().toString().toLowerCase(Locale.ENGLISH).contains(Stomp.Headers.Connect.PASSCODE)) {
191                    buffer.append("*****");
192                } else {
193                    buffer.append(entry.getValue());
194                }
195                buffer.append("\n");
196            }
197            buffer.append("\n");
198            if (getContent() != null) {
199                try {
200                    String contentString = new String(getContent(), "UTF-8");
201                    if (forLogging) {
202                        contentString = MarshallingSupport.truncate64(contentString);
203                    }
204                    buffer.append(contentString);
205                } catch (Throwable e) {
206                    buffer.append(Arrays.toString(getContent()));
207                }
208            }
209            // terminate the frame
210            buffer.append('\u0000');
211            return buffer.toString();
212        }
213    }