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.Map; 023 024import org.apache.activemq.command.Command; 025import org.apache.activemq.command.Endpoint; 026import org.apache.activemq.command.Response; 027import org.apache.activemq.state.CommandVisitor; 028import 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 */ 035public 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}