001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022/* 023 * www.openamf.org 024 * 025 * Distributable under LGPL license. 026 * See terms of license at gnu.org. 027 */ 028 029package org.granite.messaging.amf; 030 031import java.io.Serializable; 032import java.lang.reflect.Array; 033import java.util.ArrayList; 034import java.util.List; 035 036import flex.messaging.messages.Message; 037 038/** 039 * AMF Body 040 * 041 * @author Jason Calabrese <jasonc@missionvi.com> 042 * @author Pat Maddox <pergesu@users.sourceforge.net> 043 * @see AMF0Header 044 * @see AMF0Message 045 * @version $Revision: 1.19 $, $Date: 2003/09/20 01:05:24 $ 046 */ 047public class AMF0Body implements Serializable { 048 049 private static final long serialVersionUID = 1L; 050 051 protected String target; 052 protected String serviceName; 053 protected String serviceMethodName; 054 protected String response; 055 protected Object value; 056 protected byte type; 057 /** 058 * Unknow object type 059 */ 060 public static final byte DATA_TYPE_UNKNOWN = -1; 061 /** 062 * Number object type 063 */ 064 public static final byte DATA_TYPE_NUMBER = 0; 065 /** 066 * Boolean object type 067 */ 068 public static final byte DATA_TYPE_BOOLEAN = 1; 069 /** 070 * String object type 071 */ 072 public static final byte DATA_TYPE_STRING = 2; 073 /** 074 * Object object type 075 */ 076 public static final byte DATA_TYPE_OBJECT = 3; 077 /** 078 * Movie clip object type 079 */ 080 public static final byte DATA_TYPE_MOVIE_CLIP = 4; 081 /** 082 * NULL object type 083 */ 084 public static final byte DATA_TYPE_NULL = 5; 085 /** 086 * Undefined object type 087 */ 088 public static final byte DATA_TYPE_UNDEFINED = 6; 089 /** 090 * Reference object type 091 */ 092 public static final byte DATA_TYPE_REFERENCE_OBJECT = 7; 093 /** 094 * Mixed Array Object type 095 */ 096 public static final byte DATA_TYPE_MIXED_ARRAY = 8; 097 /** 098 * Object end type 099 */ 100 public static final byte DATA_TYPE_OBJECT_END = 9; 101 /** 102 * Array Object type 103 */ 104 public static final byte DATA_TYPE_ARRAY = 10; 105 /** 106 * Date object type 107 */ 108 public static final byte DATA_TYPE_DATE = 11; 109 /** 110 * Long String object type 111 */ 112 public static final byte DATA_TYPE_LONG_STRING = 12; 113 /** 114 * General Object type 115 */ 116 public static final byte DATA_TYPE_AS_OBJECT = 13; 117 /** 118 * RecordSet object type 119 */ 120 public static final byte DATA_TYPE_RECORDSET = 14; 121 /** 122 * XML Document object type 123 */ 124 public static final byte DATA_TYPE_XML = 15; 125 /** 126 * Custom class object type 127 */ 128 public static final byte DATA_TYPE_CUSTOM_CLASS = 16; 129 /** 130 * AMF3 data 131 */ 132 public static final byte DATA_TYPE_AMF3_OBJECT = 17; 133 134 /** 135 * AMF body with unknown type 136 * 137 * @param target 138 * @param response 139 * @param value 140 */ 141 public AMF0Body(String target, String response, Object value) { 142 this(target, response, value, DATA_TYPE_UNKNOWN); 143 } 144 145 /** 146 * AMF Body constructor 147 * 148 * @param target 149 * @param response 150 * @param value 151 * @param type 152 */ 153 public AMF0Body(String target, String response, Object value, byte type) { 154 this.response = response; 155 this.value = value; 156 this.type = type; 157 setTarget(target); 158 } 159 160 public String getTarget() { 161 return target; 162 } 163 164 public void setTarget(String target) { 165 this.target = target; 166 int dotIndex = target.lastIndexOf('.'); 167 if (dotIndex > 0) { 168 this.serviceName = target.substring(0, dotIndex); 169 this.serviceMethodName = target.substring(dotIndex + 1); 170 } 171 } 172 173 public String getServiceName() { 174 return serviceName; 175 } 176 177 public String getServiceMethodName() { 178 return serviceMethodName; 179 } 180 181 public String getResponse() { 182 return response; 183 } 184 185 public void setResponse(String response) { 186 this.response = response; 187 } 188 189 public boolean isFirstBody() { 190 return "/1".equals(response); 191 } 192 193 public int getBodyIndex() { 194 if (response != null && response.length() > 1) { 195 try { 196 return Integer.parseInt(response.substring(1)); 197 } catch (Exception e) { 198 } 199 } 200 return 0; // response starts with 1. 201 } 202 203 public Object getValue() { 204 return value; 205 } 206 207 public void setValue(Object value) { 208 this.value = value; 209 } 210 /** 211 * Returns object type 212 * 213 * @return the object type. 214 */ 215 public byte getType() { 216 return type; 217 } 218 /** 219 * Sets object type 220 * 221 * @param type 222 */ 223 public void setType(byte type) { 224 this.type = type; 225 } 226 /** 227 * Returns String description of object type 228 * 229 * @param type object type 230 * @return the object type description 231 */ 232 public static String getObjectTypeDescription(byte type) { 233 switch (type) { 234 case DATA_TYPE_UNKNOWN: 235 return "UNKNOWN"; 236 case DATA_TYPE_NUMBER: 237 return "NUMBER"; 238 case DATA_TYPE_BOOLEAN: 239 return "BOOLEAN"; 240 case DATA_TYPE_STRING: 241 return "STRING"; 242 case DATA_TYPE_OBJECT: 243 return "OBJECT"; 244 case DATA_TYPE_MOVIE_CLIP: 245 return "MOVIECLIP"; 246 case DATA_TYPE_NULL: 247 return "NULL"; 248 case DATA_TYPE_UNDEFINED: 249 return "UNDEFINED"; 250 case DATA_TYPE_REFERENCE_OBJECT: 251 return "REFERENCE"; 252 case DATA_TYPE_MIXED_ARRAY: 253 return "MIXED_ARRAY"; 254 case DATA_TYPE_OBJECT_END: 255 return "OBJECT_END"; 256 case DATA_TYPE_ARRAY: 257 return "ARRAY"; 258 case DATA_TYPE_DATE: 259 return "DATE"; 260 case DATA_TYPE_LONG_STRING: 261 return "LONG_STRING"; 262 case DATA_TYPE_AS_OBJECT: 263 return "AS_OBJECT"; 264 case DATA_TYPE_RECORDSET: 265 return "RECORDSET"; 266 case DATA_TYPE_XML: 267 return "XML"; 268 case DATA_TYPE_CUSTOM_CLASS: 269 return "CUSTOM_CLASS"; 270 case DATA_TYPE_AMF3_OBJECT: 271 return "AMF3_OBJECT"; 272 default: 273 return "UNKNOWN: 0x" + Integer.toBinaryString(type); 274 } 275 } 276 277 @Override 278 public String toString() { 279 return toString(""); 280 } 281 282 public String toString(String indent) { 283 return (new StringBuffer(1024) 284 .append('\n').append(indent).append(AMF0Body.class.getName()).append(" {") 285 .append('\n').append(indent).append(" target = ").append(getTarget()) 286 .append('\n').append(indent).append(" serviceName = ").append(getServiceName()) 287 .append('\n').append(indent).append(" serviceMethodName = ").append(getServiceMethodName()) 288 .append('\n').append(indent).append(" response = ").append(getResponse()) 289 .append('\n').append(indent).append(" type = ").append(getObjectTypeDescription(type)) 290 .append('\n').append(indent).append(" value = ").append(printValue(value, indent + " ")) 291 .append('\n').append(indent).append('}') 292 .toString() 293 ); 294 } 295 296 private static String printValue(Object value, String indent) { 297 298 if (value == null) 299 return "null"; 300 301 if (value instanceof AMF3Object) 302 return ((AMF3Object)value).toString(indent); 303 if (value instanceof Message) 304 return ((Message)value).toString(indent); 305 306 if (value.getClass().isArray()) { 307 final int length = Array.getLength(value); 308 List<Object> list = new ArrayList<Object>(length); 309 for (int i = 0; i < length; i++) 310 list.add(Array.get(value, i)); 311 value = list; 312 } 313 314 if (value instanceof List<?>) { 315 List<?> list = (List<?>)value; 316 317 StringBuilder sb = new StringBuilder(512); 318 319 final String innerIndent = indent + " "; 320 sb.append('['); 321 for (int i = 0; i < list.size(); i++) { 322 if (i > 0) 323 sb.append(','); 324 sb.append('\n').append(indent).append(" ").append(printValue(list.get(i), innerIndent)); 325 } 326 if (list.size() > 0) 327 sb.append('\n').append(indent); 328 sb.append(']'); 329 330 return sb.toString(); 331 } 332 333 return value.toString(); 334 } 335}