Source Code Cross Referenced for ServerSerializationStreamWriter.java in  » Ajax » GWT » com » google » gwt » user » server » rpc » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » GWT » com.google.gwt.user.server.rpc.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2007 Google Inc.
003:         * 
004:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005:         * use this file except in compliance with the License. You may obtain a copy of
006:         * the License at
007:         * 
008:         * http://www.apache.org/licenses/LICENSE-2.0
009:         * 
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013:         * License for the specific language governing permissions and limitations under
014:         * the License.
015:         */
016:        package com.google.gwt.user.server.rpc.impl;
017:
018:        import com.google.gwt.user.client.rpc.SerializationException;
019:        import com.google.gwt.user.client.rpc.SerializationStreamWriter;
020:        import com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter;
021:        import com.google.gwt.user.server.rpc.SerializationPolicy;
022:
023:        import java.lang.reflect.Field;
024:        import java.lang.reflect.InvocationTargetException;
025:        import java.lang.reflect.Method;
026:        import java.lang.reflect.Modifier;
027:        import java.util.ArrayList;
028:        import java.util.HashMap;
029:        import java.util.IdentityHashMap;
030:        import java.util.Map;
031:
032:        /**
033:         * For internal use only. Used for server call serialization. This class is
034:         * carefully matched with the client-side version.
035:         */
036:        public final class ServerSerializationStreamWriter extends
037:                AbstractSerializationStreamWriter {
038:
039:            /**
040:             * Enumeration used to provided typed instance writers.
041:             */
042:            private enum ValueWriter {
043:                BOOLEAN {
044:                    @Override
045:                    void write(ServerSerializationStreamWriter stream,
046:                            Object instance) {
047:                        stream
048:                                .writeBoolean(((Boolean) instance)
049:                                        .booleanValue());
050:                    }
051:                },
052:                BYTE {
053:                    @Override
054:                    void write(ServerSerializationStreamWriter stream,
055:                            Object instance) {
056:                        stream.writeByte(((Byte) instance).byteValue());
057:                    }
058:                },
059:                CHAR {
060:                    @Override
061:                    void write(ServerSerializationStreamWriter stream,
062:                            Object instance) {
063:                        stream.writeChar(((Character) instance).charValue());
064:                    }
065:                },
066:                DOUBLE {
067:                    @Override
068:                    void write(ServerSerializationStreamWriter stream,
069:                            Object instance) {
070:                        stream.writeDouble(((Double) instance).doubleValue());
071:                    }
072:                },
073:                FLOAT {
074:                    @Override
075:                    void write(ServerSerializationStreamWriter stream,
076:                            Object instance) {
077:                        stream.writeFloat(((Float) instance).floatValue());
078:                    }
079:                },
080:                INT {
081:                    @Override
082:                    void write(ServerSerializationStreamWriter stream,
083:                            Object instance) {
084:                        stream.writeInt(((Integer) instance).intValue());
085:                    }
086:                },
087:                LONG {
088:                    @Override
089:                    void write(ServerSerializationStreamWriter stream,
090:                            Object instance) {
091:                        stream.writeLong(((Long) instance).longValue());
092:                    }
093:                },
094:                OBJECT {
095:                    @Override
096:                    void write(ServerSerializationStreamWriter stream,
097:                            Object instance) throws SerializationException {
098:                        stream.writeObject(instance);
099:                    }
100:                },
101:                SHORT {
102:                    @Override
103:                    void write(ServerSerializationStreamWriter stream,
104:                            Object instance) {
105:                        stream.writeShort(((Short) instance).shortValue());
106:                    }
107:                },
108:                STRING {
109:                    @Override
110:                    void write(ServerSerializationStreamWriter stream,
111:                            Object instance) {
112:                        stream.writeString((String) instance);
113:                    }
114:                };
115:
116:                abstract void write(ServerSerializationStreamWriter stream,
117:                        Object instance) throws SerializationException;
118:            }
119:
120:            /**
121:             * Enumeration used to provided typed vector writers.
122:             */
123:            private enum VectorWriter {
124:                BOOLEAN_VECTOR {
125:                    @Override
126:                    void write(ServerSerializationStreamWriter stream,
127:                            Object instance) {
128:                        boolean[] vector = (boolean[]) instance;
129:                        stream.writeInt(vector.length);
130:                        for (int i = 0, n = vector.length; i < n; ++i) {
131:                            stream.writeBoolean(vector[i]);
132:                        }
133:                    }
134:                },
135:                BYTE_VECTOR {
136:                    @Override
137:                    void write(ServerSerializationStreamWriter stream,
138:                            Object instance) {
139:                        byte[] vector = (byte[]) instance;
140:                        stream.writeInt(vector.length);
141:                        for (int i = 0, n = vector.length; i < n; ++i) {
142:                            stream.writeByte(vector[i]);
143:                        }
144:                    }
145:                },
146:                CHAR_VECTOR {
147:                    @Override
148:                    void write(ServerSerializationStreamWriter stream,
149:                            Object instance) {
150:                        char[] vector = (char[]) instance;
151:                        stream.writeInt(vector.length);
152:                        for (int i = 0, n = vector.length; i < n; ++i) {
153:                            stream.writeChar(vector[i]);
154:                        }
155:                    }
156:                },
157:                DOUBLE_VECTOR {
158:                    @Override
159:                    void write(ServerSerializationStreamWriter stream,
160:                            Object instance) {
161:                        double[] vector = (double[]) instance;
162:                        stream.writeInt(vector.length);
163:                        for (int i = 0, n = vector.length; i < n; ++i) {
164:                            stream.writeDouble(vector[i]);
165:                        }
166:                    }
167:                },
168:                FLOAT_VECTOR {
169:                    @Override
170:                    void write(ServerSerializationStreamWriter stream,
171:                            Object instance) {
172:                        float[] vector = (float[]) instance;
173:                        stream.writeInt(vector.length);
174:                        for (int i = 0, n = vector.length; i < n; ++i) {
175:                            stream.writeFloat(vector[i]);
176:                        }
177:                    }
178:                },
179:                INT_VECTOR {
180:                    @Override
181:                    void write(ServerSerializationStreamWriter stream,
182:                            Object instance) {
183:                        int[] vector = (int[]) instance;
184:                        stream.writeInt(vector.length);
185:                        for (int i = 0, n = vector.length; i < n; ++i) {
186:                            stream.writeInt(vector[i]);
187:                        }
188:                    }
189:                },
190:                LONG_VECTOR {
191:                    @Override
192:                    void write(ServerSerializationStreamWriter stream,
193:                            Object instance) {
194:                        long[] vector = (long[]) instance;
195:                        stream.writeInt(vector.length);
196:                        for (int i = 0, n = vector.length; i < n; ++i) {
197:                            stream.writeLong(vector[i]);
198:                        }
199:                    }
200:                },
201:                OBJECT_VECTOR {
202:                    @Override
203:                    void write(ServerSerializationStreamWriter stream,
204:                            Object instance) throws SerializationException {
205:                        Object[] vector = (Object[]) instance;
206:                        stream.writeInt(vector.length);
207:                        for (int i = 0, n = vector.length; i < n; ++i) {
208:                            stream.writeObject(vector[i]);
209:                        }
210:                    }
211:                },
212:                SHORT_VECTOR {
213:                    @Override
214:                    void write(ServerSerializationStreamWriter stream,
215:                            Object instance) {
216:                        short[] vector = (short[]) instance;
217:                        stream.writeInt(vector.length);
218:                        for (int i = 0, n = vector.length; i < n; ++i) {
219:                            stream.writeShort(vector[i]);
220:                        }
221:                    }
222:                },
223:                STRING_VECTOR {
224:                    @Override
225:                    void write(ServerSerializationStreamWriter stream,
226:                            Object instance) {
227:                        String[] vector = (String[]) instance;
228:                        stream.writeInt(vector.length);
229:                        for (int i = 0, n = vector.length; i < n; ++i) {
230:                            stream.writeString(vector[i]);
231:                        }
232:                    }
233:                };
234:
235:                abstract void write(ServerSerializationStreamWriter stream,
236:                        Object instance) throws SerializationException;
237:            }
238:
239:            private static final char NON_BREAKING_HYPHEN = '\u2011';
240:
241:            /**
242:             * Number of escaped JS Chars.
243:             */
244:            private static final int NUMBER_OF_JS_ESCAPED_CHARS = 128;
245:
246:            /**
247:             * A list of any characters that need escaping when printing a JavaScript
248:             * string literal. Contains a 0 if the character does not need escaping,
249:             * otherwise contains the character to escape with.
250:             */
251:            private static final char[] JS_CHARS_ESCAPED = new char[NUMBER_OF_JS_ESCAPED_CHARS];
252:
253:            /**
254:             * This defines the character used by JavaScript to mark the start of an
255:             * escape sequence.
256:             */
257:            private static final char JS_ESCAPE_CHAR = '\\';
258:
259:            /**
260:             * This defines the character used to enclose JavaScript strings.
261:             */
262:            private static final char JS_QUOTE_CHAR = '\"';
263:
264:            /**
265:             * Index into this array using a nibble, 4 bits, to get the corresponding
266:             * hexa-decimal character representation.
267:             */
268:            private static final char NIBBLE_TO_HEX_CHAR[] = { '0', '1', '2',
269:                    '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
270:                    'F' };
271:
272:            /**
273:             * Map of {@link Class} objects to {@link ValueWriter}s.
274:             */
275:            private static final Map<Class<?>, ValueWriter> CLASS_TO_VALUE_WRITER = new IdentityHashMap<Class<?>, ValueWriter>();
276:
277:            /**
278:             * Map of {@link Class} vector objects to {@link VectorWriter}s.
279:             */
280:            private static final Map<Class<?>, VectorWriter> CLASS_TO_VECTOR_WRITER = new IdentityHashMap<Class<?>, VectorWriter>();
281:
282:            static {
283:                /*
284:                 * NOTE: The JS VM in IE6 & IE7 do not interpret \v correctly. They convert
285:                 * JavaScript Vertical Tab character '\v' into 'v'. As such, we do not use
286:                 * the short form of the unicode escape here.
287:                 */
288:                JS_CHARS_ESCAPED['\u0000'] = '0';
289:                JS_CHARS_ESCAPED['\b'] = 'b';
290:                JS_CHARS_ESCAPED['\t'] = 't';
291:                JS_CHARS_ESCAPED['\n'] = 'n';
292:                JS_CHARS_ESCAPED['\f'] = 'f';
293:                JS_CHARS_ESCAPED['\r'] = 'r';
294:                JS_CHARS_ESCAPED[JS_ESCAPE_CHAR] = JS_ESCAPE_CHAR;
295:                JS_CHARS_ESCAPED[JS_QUOTE_CHAR] = JS_QUOTE_CHAR;
296:
297:                CLASS_TO_VECTOR_WRITER.put(boolean[].class,
298:                        VectorWriter.BOOLEAN_VECTOR);
299:                CLASS_TO_VECTOR_WRITER.put(byte[].class,
300:                        VectorWriter.BYTE_VECTOR);
301:                CLASS_TO_VECTOR_WRITER.put(char[].class,
302:                        VectorWriter.CHAR_VECTOR);
303:                CLASS_TO_VECTOR_WRITER.put(double[].class,
304:                        VectorWriter.DOUBLE_VECTOR);
305:                CLASS_TO_VECTOR_WRITER.put(float[].class,
306:                        VectorWriter.FLOAT_VECTOR);
307:                CLASS_TO_VECTOR_WRITER
308:                        .put(int[].class, VectorWriter.INT_VECTOR);
309:                CLASS_TO_VECTOR_WRITER.put(long[].class,
310:                        VectorWriter.LONG_VECTOR);
311:                CLASS_TO_VECTOR_WRITER.put(Object[].class,
312:                        VectorWriter.OBJECT_VECTOR);
313:                CLASS_TO_VECTOR_WRITER.put(short[].class,
314:                        VectorWriter.SHORT_VECTOR);
315:                CLASS_TO_VECTOR_WRITER.put(String[].class,
316:                        VectorWriter.STRING_VECTOR);
317:
318:                CLASS_TO_VALUE_WRITER.put(boolean.class, ValueWriter.BOOLEAN);
319:                CLASS_TO_VALUE_WRITER.put(byte.class, ValueWriter.BYTE);
320:                CLASS_TO_VALUE_WRITER.put(char.class, ValueWriter.CHAR);
321:                CLASS_TO_VALUE_WRITER.put(double.class, ValueWriter.DOUBLE);
322:                CLASS_TO_VALUE_WRITER.put(float.class, ValueWriter.FLOAT);
323:                CLASS_TO_VALUE_WRITER.put(int.class, ValueWriter.INT);
324:                CLASS_TO_VALUE_WRITER.put(long.class, ValueWriter.LONG);
325:                CLASS_TO_VALUE_WRITER.put(Object.class, ValueWriter.OBJECT);
326:                CLASS_TO_VALUE_WRITER.put(short.class, ValueWriter.SHORT);
327:                CLASS_TO_VALUE_WRITER.put(String.class, ValueWriter.STRING);
328:            }
329:
330:            /**
331:             * This method takes a string and outputs a JavaScript string literal. The
332:             * data is surrounded with quotes, and any contained characters that need to
333:             * be escaped are mapped onto their escape sequence.
334:             * 
335:             * Assumptions: We are targeting a version of JavaScript that that is later
336:             * than 1.3 that supports unicode strings.
337:             */
338:            private static String escapeString(String toEscape) {
339:                // make output big enough to escape every character (plus the quotes)
340:                char[] input = toEscape.toCharArray();
341:                CharVector charVector = new CharVector(input.length * 2 + 2,
342:                        input.length);
343:
344:                charVector.add(JS_QUOTE_CHAR);
345:
346:                for (int i = 0, n = input.length; i < n; ++i) {
347:                    char c = input[i];
348:                    if (c < NUMBER_OF_JS_ESCAPED_CHARS
349:                            && JS_CHARS_ESCAPED[c] != 0) {
350:                        charVector.add(JS_ESCAPE_CHAR);
351:                        charVector.add(JS_CHARS_ESCAPED[c]);
352:                    } else if (needsUnicodeEscape(c)) {
353:                        charVector.add(JS_ESCAPE_CHAR);
354:                        unicodeEscape(c, charVector);
355:                    } else {
356:                        charVector.add(c);
357:                    }
358:                }
359:
360:                charVector.add(JS_QUOTE_CHAR);
361:                return String.valueOf(charVector.asArray(), 0, charVector
362:                        .getSize());
363:            }
364:
365:            /**
366:             * Returns the {@link Class} instance to use for serialization.  Enumerations 
367:             * are serialized as their declaring class while all others are serialized 
368:             * using their true class instance.
369:             */
370:            private static Class<?> getClassForSerialization(Object instance) {
371:                assert (instance != null);
372:
373:                if (instance instanceof  Enum) {
374:                    Enum<?> e = (Enum<?>) instance;
375:                    return e.getDeclaringClass();
376:                } else {
377:                    return instance.getClass();
378:                }
379:            }
380:
381:            /**
382:             * Returns <code>true</code> if the character requires the \\uXXXX unicode
383:   * character escape sequence. This is necessary if the raw character could be
384:   * consumed and/or interpreted as a special character when the JSON encoded
385:   * response is evaluated. For example, 0x2028 and 0x2029 are alternate line
386:   * endings for JS per ECMA-232, which are respected by Firefox and Mozilla.
387:   * 
388:   * @param ch character to check
389:   * @return <code>true</code> if the character requires the \\uXXXX unicode
390:   *         character escape
391:   * 
392:   * Notes:
393:   * <ol>
394:   * <li> The following cases are a more conservative set of cases which are are
395:   * in the future proofing space as opposed to the required minimal set. We
396:   * could remove these and still pass our tests.
397:   * <ul>
398:   * <li>UNASSIGNED - 6359</li>
399:   * <li>NON_SPACING_MARK - 530</li>
400:   * <li>ENCLOSING_MARK - 10</li>
401:   * <li>COMBINING_SPACE_MARK - 131</li>
402:   * <li>SPACE_SEPARATOR - 19</li>
403:   * <li>CONTROL - 65</li>
404:   * <li>PRIVATE_USE - 6400</li>
405:   * <li>DASH_PUNCTUATION - 1</li>
406:   * <li>Total Characters Escaped: 13515</li>
407:   * </ul>
408:   * </li>
409:   * <li> The following cases are the minimal amount of escaping required to
410:   * prevent test failure.
411:   * <ul>
412:   * <li>LINE_SEPARATOR - 1</li>
413:   * <li>PARAGRAPH_SEPARATOR - 1</li>
414:   * <li>FORMAT - 32</li>
415:   * <li>SURROGATE - 2048</li>
416:   * <li>Total Characters Escaped: 2082</li>
417:   * </li>
418:   * </ul>
419:   * </li>
420:   * </ol>
421:   */
422:            private static boolean needsUnicodeEscape(char ch) {
423:                switch (Character.getType(ch)) {
424:                // Conservative
425:                case Character.COMBINING_SPACING_MARK:
426:                case Character.ENCLOSING_MARK:
427:                case Character.NON_SPACING_MARK:
428:                case Character.UNASSIGNED:
429:                case Character.PRIVATE_USE:
430:                case Character.SPACE_SEPARATOR:
431:                case Character.CONTROL:
432:
433:                    // Minimal
434:                case Character.LINE_SEPARATOR:
435:                case Character.FORMAT:
436:                case Character.PARAGRAPH_SEPARATOR:
437:                case Character.SURROGATE:
438:                    return true;
439:
440:                default:
441:                    if (ch == NON_BREAKING_HYPHEN) {
442:                        // This can be expanded into a break followed by a hyphen
443:                        return true;
444:                    }
445:                    break;
446:                }
447:
448:                return false;
449:            }
450:
451:            /**
452:             * Writes either the two or four character escape sequence for a character.
453:             * 
454:             * 
455:             * @param ch character to unicode escape
456:             * @param charVector char vector to receive the unicode escaped representation
457:             */
458:            private static void unicodeEscape(char ch, CharVector charVector) {
459:                if (ch < 256) {
460:                    charVector.add('x');
461:                    charVector.add(NIBBLE_TO_HEX_CHAR[(ch >> 4) & 0x0F]);
462:                    charVector.add(NIBBLE_TO_HEX_CHAR[ch & 0x0F]);
463:                } else {
464:                    charVector.add('u');
465:                    charVector.add(NIBBLE_TO_HEX_CHAR[(ch >> 12) & 0x0F]);
466:                    charVector.add(NIBBLE_TO_HEX_CHAR[(ch >> 8) & 0x0F]);
467:                    charVector.add(NIBBLE_TO_HEX_CHAR[(ch >> 4) & 0x0F]);
468:                    charVector.add(NIBBLE_TO_HEX_CHAR[ch & 0x0F]);
469:                }
470:            }
471:
472:            private int objectCount;
473:
474:            private IdentityHashMap<Object, Integer> objectMap = new IdentityHashMap<Object, Integer>();
475:
476:            private HashMap<String, Integer> stringMap = new HashMap<String, Integer>();
477:
478:            private ArrayList<String> stringTable = new ArrayList<String>();
479:
480:            private ArrayList<String> tokenList = new ArrayList<String>();
481:
482:            private int tokenListCharCount;
483:
484:            private final SerializationPolicy serializationPolicy;
485:
486:            public ServerSerializationStreamWriter(
487:                    SerializationPolicy serializationPolicy) {
488:                this .serializationPolicy = serializationPolicy;
489:            }
490:
491:            public void prepareToWrite() {
492:                objectCount = 0;
493:                objectMap.clear();
494:                tokenList.clear();
495:                tokenListCharCount = 0;
496:                stringMap.clear();
497:                stringTable.clear();
498:            }
499:
500:            public void serializeValue(Object value, Class<?> type)
501:                    throws SerializationException {
502:                ValueWriter valueWriter = CLASS_TO_VALUE_WRITER.get(type);
503:                if (valueWriter != null) {
504:                    valueWriter.write(this , value);
505:                } else {
506:                    // Arrays of primitive or reference types need to go through writeObject.
507:                    ValueWriter.OBJECT.write(this , value);
508:                }
509:            }
510:
511:            /**
512:             * Build an array of JavaScript string literals that can be decoded by the
513:             * client via the eval function.
514:             * 
515:             * NOTE: We build the array in reverse so the client can simply use the pop
516:             * function to remove the next item from the list.
517:             */
518:            @Override
519:            public String toString() {
520:                // Build a JavaScript string (with escaping, of course).
521:                // We take a guess at how big to make to buffer to avoid numerous resizes.
522:                //
523:                int capacityGuess = 2 * tokenListCharCount + 2
524:                        * tokenList.size();
525:                StringBuffer buffer = new StringBuffer(capacityGuess);
526:                buffer.append("[");
527:                writePayload(buffer);
528:                writeStringTable(buffer);
529:                writeHeader(buffer);
530:                buffer.append("]");
531:                return buffer.toString();
532:            }
533:
534:            @Override
535:            protected int addString(String string) {
536:                if (string == null) {
537:                    return 0;
538:                }
539:                Integer o = stringMap.get(string);
540:                if (o != null) {
541:                    return o;
542:                }
543:                stringTable.add(string);
544:                // index is 1-based
545:                int index = stringTable.size();
546:                stringMap.put(string, index);
547:                return index;
548:            }
549:
550:            @Override
551:            protected void append(String token) {
552:                tokenList.add(token);
553:                if (token != null) {
554:                    tokenListCharCount += token.length();
555:                }
556:            }
557:
558:            @Override
559:            protected int getIndexForObject(Object instance) {
560:                Integer o = objectMap.get(instance);
561:                if (o != null) {
562:                    return o;
563:                }
564:                return -1;
565:            }
566:
567:            @Override
568:            protected String getObjectTypeSignature(Object instance) {
569:                assert (instance != null);
570:
571:                Class<?> clazz = getClassForSerialization(instance);
572:                if (shouldEnforceTypeVersioning()) {
573:                    return SerializabilityUtil
574:                            .encodeSerializedInstanceReference(clazz);
575:                } else {
576:                    return SerializabilityUtil.getSerializedTypeName(clazz);
577:                }
578:            }
579:
580:            @Override
581:            protected void saveIndexForObject(Object instance) {
582:                objectMap.put(instance, objectCount++);
583:            }
584:
585:            @Override
586:            protected void serialize(Object instance, String typeSignature)
587:                    throws SerializationException {
588:                assert (instance != null);
589:
590:                Class<?> clazz = getClassForSerialization(instance);
591:
592:                serializationPolicy.validateSerialize(clazz);
593:
594:                serializeImpl(instance, clazz);
595:            }
596:
597:            /**
598:             * Serialize an instance that is an array. Will default to serializing the
599:             * instance as an Object vector if the instance is not a vector of primitives,
600:             * Strings or Object.
601:             * 
602:             * @param instanceClass
603:             * @param instance
604:             * @throws SerializationException
605:             */
606:            private void serializeArray(Class<?> instanceClass, Object instance)
607:                    throws SerializationException {
608:                assert (instanceClass.isArray());
609:
610:                VectorWriter instanceWriter = CLASS_TO_VECTOR_WRITER
611:                        .get(instanceClass);
612:                if (instanceWriter != null) {
613:                    instanceWriter.write(this , instance);
614:                } else {
615:                    VectorWriter.OBJECT_VECTOR.write(this , instance);
616:                }
617:            }
618:
619:            private void serializeClass(Object instance, Class<?> instanceClass)
620:                    throws SerializationException {
621:                assert (instance != null);
622:
623:                Field[] serializableFields = SerializabilityUtil
624:                        .applyFieldSerializationPolicy(instanceClass);
625:                for (Field declField : serializableFields) {
626:                    assert (declField != null);
627:
628:                    boolean isAccessible = declField.isAccessible();
629:                    boolean needsAccessOverride = !isAccessible
630:                            && !Modifier.isPublic(declField.getModifiers());
631:                    if (needsAccessOverride) {
632:                        // Override the access restrictions
633:                        declField.setAccessible(true);
634:                    }
635:
636:                    Object value;
637:                    try {
638:                        value = declField.get(instance);
639:                        serializeValue(value, declField.getType());
640:
641:                    } catch (IllegalArgumentException e) {
642:                        throw new SerializationException(e);
643:
644:                    } catch (IllegalAccessException e) {
645:                        throw new SerializationException(e);
646:                    }
647:
648:                    if (needsAccessOverride) {
649:                        // Restore the access restrictions
650:                        declField.setAccessible(isAccessible);
651:                    }
652:                }
653:
654:                Class<?> super Class = instanceClass.getSuperclass();
655:                if (serializationPolicy.shouldSerializeFields(super Class)) {
656:                    serializeImpl(instance, super Class);
657:                }
658:            }
659:
660:            private void serializeImpl(Object instance, Class<?> instanceClass)
661:                    throws SerializationException {
662:                assert (instance != null);
663:
664:                Class<?> customSerializer = SerializabilityUtil
665:                        .hasCustomFieldSerializer(instanceClass);
666:                if (customSerializer != null) {
667:                    // Use custom field serializer
668:                    serializeWithCustomSerializer(customSerializer, instance,
669:                            instanceClass);
670:                } else if (instanceClass.isArray()) {
671:                    serializeArray(instanceClass, instance);
672:                } else if (instanceClass.isEnum()) {
673:                    writeInt(((Enum<?>) instance).ordinal());
674:                } else {
675:                    // Regular class instance
676:                    serializeClass(instance, instanceClass);
677:                }
678:            }
679:
680:            private void serializeWithCustomSerializer(
681:                    Class<?> customSerializer, Object instance,
682:                    Class<?> instanceClass) throws SerializationException {
683:
684:                Method serialize;
685:                try {
686:                    assert (!instanceClass.isArray());
687:
688:                    serialize = customSerializer.getMethod("serialize",
689:                            SerializationStreamWriter.class, instanceClass);
690:
691:                    serialize.invoke(null, this , instance);
692:
693:                } catch (SecurityException e) {
694:                    throw new SerializationException(e);
695:
696:                } catch (NoSuchMethodException e) {
697:                    throw new SerializationException(e);
698:
699:                } catch (IllegalArgumentException e) {
700:                    throw new SerializationException(e);
701:
702:                } catch (IllegalAccessException e) {
703:                    throw new SerializationException(e);
704:
705:                } catch (InvocationTargetException e) {
706:                    throw new SerializationException(e);
707:                }
708:            }
709:
710:            /**
711:             * Notice that the field are written in reverse order that the client can just
712:             * pop items out of the stream.
713:             */
714:            private void writeHeader(StringBuffer buffer) {
715:                buffer.append(",");
716:                buffer.append(getFlags());
717:                buffer.append(",");
718:                buffer.append(getVersion());
719:            }
720:
721:            private void writePayload(StringBuffer buffer) {
722:                for (int i = tokenList.size() - 1; i >= 0; --i) {
723:                    String token = tokenList.get(i);
724:                    buffer.append(token);
725:                    if (i > 0) {
726:                        buffer.append(",");
727:                    }
728:                }
729:            }
730:
731:            private void writeStringTable(StringBuffer buffer) {
732:                if (tokenList.size() > 0) {
733:                    buffer.append(",");
734:                }
735:                buffer.append("[");
736:                for (int i = 0, c = stringTable.size(); i < c; ++i) {
737:                    if (i > 0) {
738:                        buffer.append(",");
739:                    }
740:                    buffer.append(escapeString(stringTable.get(i)));
741:                }
742:                buffer.append("]");
743:            }
744:        }
ww___w___.__j_av_a__2__s_.___co___m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.