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
029 package org.granite.messaging.amf;
030
031 import java.io.Serializable;
032 import java.lang.reflect.Array;
033 import java.util.ArrayList;
034 import java.util.List;
035
036 import 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 */
047 public 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 }