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.command; 018 019import java.io.DataInputStream; 020import java.io.DataOutputStream; 021import java.io.IOException; 022import java.util.Arrays; 023import java.util.Collections; 024import java.util.HashMap; 025import java.util.Map; 026import org.apache.activemq.state.CommandVisitor; 027import org.apache.activemq.util.ByteArrayInputStream; 028import org.apache.activemq.util.ByteArrayOutputStream; 029import org.apache.activemq.util.ByteSequence; 030import org.apache.activemq.util.MarshallingSupport; 031import org.apache.activemq.wireformat.WireFormat; 032 033/** 034 * @openwire:marshaller code="1" 035 * 036 */ 037public class WireFormatInfo implements Command, MarshallAware { 038 039 public static final byte DATA_STRUCTURE_TYPE = CommandTypes.WIREFORMAT_INFO; 040 private static final int MAX_PROPERTY_SIZE = 1024 * 4; 041 private static final byte MAGIC[] = new byte[] {'A', 'c', 't', 'i', 'v', 'e', 'M', 'Q'}; 042 043 protected byte magic[] = MAGIC; 044 protected int version; 045 protected ByteSequence marshalledProperties; 046 047 protected transient Map<String, Object> properties; 048 private transient Endpoint from; 049 private transient Endpoint to; 050 051 public byte getDataStructureType() { 052 return DATA_STRUCTURE_TYPE; 053 } 054 055 public boolean isWireFormatInfo() { 056 return true; 057 } 058 059 public boolean isMarshallAware() { 060 return true; 061 } 062 063 /** 064 * @openwire:property version=1 size=8 testSize=-1 065 */ 066 public byte[] getMagic() { 067 return magic; 068 } 069 070 public void setMagic(byte[] magic) { 071 this.magic = magic; 072 } 073 074 /** 075 * @openwire:property version=1 076 */ 077 public int getVersion() { 078 return version; 079 } 080 081 public void setVersion(int version) { 082 this.version = version; 083 } 084 085 /** 086 * @openwire:property version=1 087 */ 088 public ByteSequence getMarshalledProperties() { 089 return marshalledProperties; 090 } 091 092 public void setMarshalledProperties(ByteSequence marshalledProperties) { 093 this.marshalledProperties = marshalledProperties; 094 } 095 096 /** 097 * The endpoint within the transport where this message came from. 098 */ 099 public Endpoint getFrom() { 100 return from; 101 } 102 103 public void setFrom(Endpoint from) { 104 this.from = from; 105 } 106 107 /** 108 * The endpoint within the transport where this message is going to - null 109 * means all endpoints. 110 */ 111 public Endpoint getTo() { 112 return to; 113 } 114 115 public void setTo(Endpoint to) { 116 this.to = to; 117 } 118 119 // //////////////////// 120 // 121 // Implementation Methods. 122 // 123 // //////////////////// 124 125 public Object getProperty(String name) throws IOException { 126 if (properties == null) { 127 if (marshalledProperties == null) { 128 return null; 129 } 130 properties = unmarsallProperties(marshalledProperties); 131 } 132 return properties.get(name); 133 } 134 135 @SuppressWarnings("unchecked") 136 public Map<String, Object> getProperties() throws IOException { 137 if (properties == null) { 138 if (marshalledProperties == null) { 139 return Collections.EMPTY_MAP; 140 } 141 properties = unmarsallProperties(marshalledProperties); 142 } 143 return Collections.unmodifiableMap(properties); 144 } 145 146 public void clearProperties() { 147 marshalledProperties = null; 148 properties = null; 149 } 150 151 public void setProperty(String name, Object value) throws IOException { 152 lazyCreateProperties(); 153 properties.put(name, value); 154 } 155 156 protected void lazyCreateProperties() throws IOException { 157 if (properties == null) { 158 if (marshalledProperties == null) { 159 properties = new HashMap<String, Object>(); 160 } else { 161 properties = unmarsallProperties(marshalledProperties); 162 marshalledProperties = null; 163 } 164 } 165 } 166 167 private Map<String, Object> unmarsallProperties(ByteSequence marshalledProperties) throws IOException { 168 return MarshallingSupport.unmarshalPrimitiveMap(new DataInputStream(new ByteArrayInputStream(marshalledProperties)), MAX_PROPERTY_SIZE); 169 } 170 171 public void beforeMarshall(WireFormat wireFormat) throws IOException { 172 // Need to marshal the properties. 173 if (marshalledProperties == null && properties != null) { 174 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 175 DataOutputStream os = new DataOutputStream(baos); 176 MarshallingSupport.marshalPrimitiveMap(properties, os); 177 os.close(); 178 marshalledProperties = baos.toByteSequence(); 179 } 180 } 181 182 public void afterMarshall(WireFormat wireFormat) throws IOException { 183 } 184 185 public void beforeUnmarshall(WireFormat wireFormat) throws IOException { 186 } 187 188 public void afterUnmarshall(WireFormat wireFormat) throws IOException { 189 } 190 191 public boolean isValid() { 192 return magic != null && Arrays.equals(magic, MAGIC); 193 } 194 195 public void setResponseRequired(boolean responseRequired) { 196 } 197 198 /** 199 * @throws IOException 200 */ 201 public boolean isCacheEnabled() throws IOException { 202 return Boolean.TRUE == getProperty("CacheEnabled"); 203 } 204 205 public void setCacheEnabled(boolean cacheEnabled) throws IOException { 206 setProperty("CacheEnabled", cacheEnabled ? Boolean.TRUE : Boolean.FALSE); 207 } 208 209 /** 210 * @throws IOException 211 */ 212 public boolean isStackTraceEnabled() throws IOException { 213 return Boolean.TRUE == getProperty("StackTraceEnabled"); 214 } 215 216 public void setStackTraceEnabled(boolean stackTraceEnabled) throws IOException { 217 setProperty("StackTraceEnabled", stackTraceEnabled ? Boolean.TRUE : Boolean.FALSE); 218 } 219 220 /** 221 * @throws IOException 222 */ 223 public boolean isTcpNoDelayEnabled() throws IOException { 224 return Boolean.TRUE == getProperty("TcpNoDelayEnabled"); 225 } 226 227 public void setTcpNoDelayEnabled(boolean tcpNoDelayEnabled) throws IOException { 228 setProperty("TcpNoDelayEnabled", tcpNoDelayEnabled ? Boolean.TRUE : Boolean.FALSE); 229 } 230 231 /** 232 * @throws IOException 233 */ 234 public boolean isSizePrefixDisabled() throws IOException { 235 return Boolean.TRUE == getProperty("SizePrefixDisabled"); 236 } 237 238 public void setSizePrefixDisabled(boolean prefixPacketSize) throws IOException { 239 setProperty("SizePrefixDisabled", prefixPacketSize ? Boolean.TRUE : Boolean.FALSE); 240 } 241 242 /** 243 * @throws IOException 244 */ 245 public boolean isTightEncodingEnabled() throws IOException { 246 return Boolean.TRUE == getProperty("TightEncodingEnabled"); 247 } 248 249 public void setTightEncodingEnabled(boolean tightEncodingEnabled) throws IOException { 250 setProperty("TightEncodingEnabled", tightEncodingEnabled ? Boolean.TRUE : Boolean.FALSE); 251 } 252 253 /** 254 * @throws IOException 255 */ 256 public long getMaxInactivityDuration() throws IOException { 257 Long l = (Long)getProperty("MaxInactivityDuration"); 258 return l == null ? 0 : l.longValue(); 259 } 260 261 public void setMaxInactivityDuration(long maxInactivityDuration) throws IOException { 262 setProperty("MaxInactivityDuration", new Long(maxInactivityDuration)); 263 } 264 265 public long getMaxInactivityDurationInitalDelay() throws IOException { 266 Long l = (Long)getProperty("MaxInactivityDurationInitalDelay"); 267 return l == null ? 0 : l.longValue(); 268 } 269 270 public void setMaxInactivityDurationInitalDelay(long maxInactivityDurationInitalDelay) throws IOException { 271 setProperty("MaxInactivityDurationInitalDelay", new Long(maxInactivityDurationInitalDelay)); 272 } 273 274 public long getMaxFrameSize() throws IOException { 275 Long l = (Long)getProperty("MaxFrameSize"); 276 return l == null ? 0 : l.longValue(); 277 } 278 279 public void setMaxFrameSize(long maxFrameSize) throws IOException { 280 setProperty("MaxFrameSize", new Long(maxFrameSize)); 281 } 282 283 284 285 /** 286 * @throws IOException 287 */ 288 public int getCacheSize() throws IOException { 289 Integer i = (Integer)getProperty("CacheSize"); 290 return i == null ? 0 : i.intValue(); 291 } 292 293 public void setCacheSize(int cacheSize) throws IOException { 294 setProperty("CacheSize", new Integer(cacheSize)); 295 } 296 297 public Response visit(CommandVisitor visitor) throws Exception { 298 return visitor.processWireFormat(this); 299 } 300 301 @Override 302 public String toString() { 303 Map<String, Object> p = null; 304 try { 305 p = getProperties(); 306 } catch (IOException ignore) { 307 } 308 return "WireFormatInfo { version=" + version + ", properties=" + p + ", magic=" + toString(magic) + "}"; 309 } 310 311 private String toString(byte[] data) { 312 StringBuffer sb = new StringBuffer(); 313 sb.append('['); 314 for (int i = 0; i < data.length; i++) { 315 if (i != 0) { 316 sb.append(','); 317 } 318 sb.append((char)data[i]); 319 } 320 sb.append(']'); 321 return sb.toString(); 322 } 323 324 // ///////////////////////////////////////////////////////////// 325 // 326 // This are not implemented. 327 // 328 // ///////////////////////////////////////////////////////////// 329 330 public void setCommandId(int value) { 331 } 332 333 public int getCommandId() { 334 return 0; 335 } 336 337 public boolean isResponseRequired() { 338 return false; 339 } 340 341 public boolean isResponse() { 342 return false; 343 } 344 345 public boolean isBrokerInfo() { 346 return false; 347 } 348 349 public boolean isMessageDispatch() { 350 return false; 351 } 352 353 public boolean isMessage() { 354 return false; 355 } 356 357 public boolean isMessageAck() { 358 return false; 359 } 360 361 public boolean isMessageDispatchNotification() { 362 return false; 363 } 364 365 public boolean isShutdownInfo() { 366 return false; 367 } 368 369 public boolean isConnectionControl() { 370 return false; 371 } 372 373 public void setCachedMarshalledForm(WireFormat wireFormat, ByteSequence data) { 374 } 375 376 public ByteSequence getCachedMarshalledForm(WireFormat wireFormat) { 377 return null; 378 } 379 380}