Source Code Cross Referenced for DNAEncodingImpl.java in  » Net » Terracotta » com » tc » object » dna » 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 » Net » Terracotta » com.tc.object.dna.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
0003:         * notice. All rights reserved.
0004:         */
0005:        package com.tc.object.dna.impl;
0006:
0007:        import com.tc.exception.TCRuntimeException;
0008:        import com.tc.io.TCByteArrayOutputStream;
0009:        import com.tc.io.TCDataInput;
0010:        import com.tc.io.TCDataOutput;
0011:        import com.tc.logging.TCLogger;
0012:        import com.tc.logging.TCLogging;
0013:        import com.tc.object.LiteralValues;
0014:        import com.tc.object.ObjectID;
0015:        import com.tc.object.dna.api.DNAEncoding;
0016:        import com.tc.object.loaders.ClassProvider;
0017:        import com.tc.object.loaders.NamedClassLoader;
0018:        import com.tc.properties.TCPropertiesImpl;
0019:        import com.tc.util.Assert;
0020:
0021:        import gnu.trove.TObjectIntHashMap;
0022:
0023:        import java.io.ByteArrayInputStream;
0024:        import java.io.IOException;
0025:        import java.io.UnsupportedEncodingException;
0026:        import java.lang.reflect.Array;
0027:        import java.lang.reflect.Constructor;
0028:        import java.lang.reflect.Field;
0029:        import java.lang.reflect.InvocationTargetException;
0030:        import java.lang.reflect.Method;
0031:        import java.math.BigDecimal;
0032:        import java.math.BigInteger;
0033:        import java.util.Currency;
0034:        import java.util.zip.DeflaterOutputStream;
0035:        import java.util.zip.InflaterInputStream;
0036:
0037:        /**
0038:         * Utility for encoding/decoding DNA
0039:         */
0040:        public class DNAEncodingImpl implements  DNAEncoding {
0041:
0042:            // XXX: These warning thresholds should be done in a non-static way so they can be made configurable
0043:            // and architecture sensitive.
0044:            private static final int WARN_THRESHOLD = 8 * 1000 * 1000;
0045:            private static final int BOOLEAN_WARN = WARN_THRESHOLD / 1;
0046:            private static final int BYTE_WARN = WARN_THRESHOLD / 1;
0047:            private static final int CHAR_WARN = WARN_THRESHOLD / 2;
0048:            private static final int DOUBLE_WARN = WARN_THRESHOLD / 8;
0049:            private static final int FLOAT_WARN = WARN_THRESHOLD / 4;
0050:            private static final int INT_WARN = WARN_THRESHOLD / 4;
0051:            private static final int LONG_WARN = WARN_THRESHOLD / 8;
0052:            private static final int SHORT_WARN = WARN_THRESHOLD / 2;
0053:            private static final int REF_WARN = WARN_THRESHOLD / 4;
0054:
0055:            static final byte LOGICAL_ACTION_TYPE = 1;
0056:            static final byte PHYSICAL_ACTION_TYPE = 2;
0057:            static final byte ARRAY_ELEMENT_ACTION_TYPE = 3;
0058:            static final byte ENTIRE_ARRAY_ACTION_TYPE = 4;
0059:            static final byte LITERAL_VALUE_ACTION_TYPE = 5;
0060:            static final byte PHYSICAL_ACTION_TYPE_REF_OBJECT = 6;
0061:            static final byte SUB_ARRAY_ACTION_TYPE = 7;
0062:
0063:            private static final LiteralValues literalValues = new LiteralValues();
0064:            private static final TCLogger logger = TCLogging
0065:                    .getLogger(DNAEncodingImpl.class);
0066:
0067:            private static final byte TYPE_ID_REFERENCE = 1;
0068:            private static final byte TYPE_ID_BOOLEAN = 2;
0069:            private static final byte TYPE_ID_BYTE = 3;
0070:            private static final byte TYPE_ID_CHAR = 4;
0071:            private static final byte TYPE_ID_DOUBLE = 5;
0072:            private static final byte TYPE_ID_FLOAT = 6;
0073:            private static final byte TYPE_ID_INT = 7;
0074:            private static final byte TYPE_ID_LONG = 10;
0075:            private static final byte TYPE_ID_SHORT = 11;
0076:            private static final byte TYPE_ID_STRING = 12;
0077:            private static final byte TYPE_ID_STRING_BYTES = 13;
0078:            private static final byte TYPE_ID_ARRAY = 14;
0079:            private static final byte TYPE_ID_JAVA_LANG_CLASS = 15;
0080:            private static final byte TYPE_ID_JAVA_LANG_CLASS_HOLDER = 16;
0081:            private static final byte TYPE_ID_BIG_INTEGER = 17;
0082:            private static final byte TYPE_ID_STACK_TRACE_ELEMENT = 18;
0083:            private static final byte TYPE_ID_BIG_DECIMAL = 19;
0084:            private static final byte TYPE_ID_JAVA_LANG_CLASSLOADER = 20;
0085:            private static final byte TYPE_ID_JAVA_LANG_CLASSLOADER_HOLDER = 21;
0086:            private static final byte TYPE_ID_ENUM = 22;
0087:            private static final byte TYPE_ID_ENUM_HOLDER = 23;
0088:            private static final byte TYPE_ID_CURRENCY = 24;
0089:            private static final byte TYPE_ID_STRING_COMPRESSED = 25;
0090:            //  private static final byte          TYPE_ID_URL                          = 26;
0091:
0092:            private static final byte ARRAY_TYPE_PRIMITIVE = 1;
0093:            private static final byte ARRAY_TYPE_NON_PRIMITIVE = 2;
0094:
0095:            private final ClassProvider classProvider;
0096:            private final byte policy;
0097:
0098:            private static final ClassProvider FAILURE_PROVIDER = new FailureClassProvider();
0099:            private static final ClassProvider LOCAL_PROVIDER = new LocalClassProvider();
0100:
0101:            private static final boolean STRING_COMPRESSION_ENABLED = TCPropertiesImpl
0102:                    .getProperties().getBoolean(
0103:                            "l1.transactionmanager.strings.compress.enabled");
0104:            private static final boolean STRING_COMPRESSION_LOGGING_ENABLED = TCPropertiesImpl
0105:                    .getProperties()
0106:                    .getBoolean(
0107:                            "l1.transactionmanager.strings.compress.logging.enabled");
0108:            private static final int STRING_COMPRESSION_MIN_SIZE = TCPropertiesImpl
0109:                    .getProperties().getInt(
0110:                            "l1.transactionmanager.strings.compress.minSize");
0111:
0112:            /**
0113:             * Used in the Applicators. The policy is set to APPLICATOR.
0114:             */
0115:            public DNAEncodingImpl(ClassProvider classProvider) {
0116:                this .classProvider = classProvider;
0117:                this .policy = APPLICATOR;
0118:            }
0119:
0120:            public DNAEncodingImpl(byte policy) {
0121:                this .policy = policy;
0122:                // you only want this version on the server where you won't be expanding java.lang.Class instances
0123:                if (policy == STORAGE) {
0124:                    this .classProvider = FAILURE_PROVIDER;
0125:                } else if (policy == SERIALIZER) {
0126:                    this .classProvider = LOCAL_PROVIDER;
0127:                } else {
0128:                    throw new AssertionError("Policy not valid : " + policy
0129:                            + " : For APPLICATORS use the other contructor !");
0130:                }
0131:            }
0132:
0133:            public byte getPolicy() {
0134:                return this .policy;
0135:            }
0136:
0137:            public void encodeClassLoader(Object value, TCDataOutput output) {
0138:                output.writeByte(TYPE_ID_JAVA_LANG_CLASSLOADER);
0139:                writeString(classProvider
0140:                        .getLoaderDescriptionFor((ClassLoader) value), output);
0141:            }
0142:
0143:            /**
0144:             * The reason that we use reflection here is that Enum is a jdk 1.5 construct and this project is jdk 1.4 compliance.
0145:             */
0146:            private Object getEnumName(Object enumObject) {
0147:                try {
0148:                    Method m = enumObject.getClass().getMethod("name",
0149:                            new Class[0]);
0150:                    m.setAccessible(true);
0151:                    Object val;
0152:                    val = m.invoke(enumObject, new Object[0]);
0153:                    return val;
0154:                } catch (IllegalArgumentException e) {
0155:                    throw new TCRuntimeException(e);
0156:                } catch (IllegalAccessException e) {
0157:                    throw new TCRuntimeException(e);
0158:                } catch (InvocationTargetException e) {
0159:                    throw new TCRuntimeException(e);
0160:                } catch (SecurityException e) {
0161:                    throw new TCRuntimeException(e);
0162:                } catch (NoSuchMethodException e) {
0163:                    throw new TCRuntimeException(e);
0164:                }
0165:            }
0166:
0167:            public void encode(Object value, TCDataOutput output) {
0168:                if (value == null) {
0169:                    // Normally Null values should have already been converted to null ObjectID, but this is not true when there are
0170:                    // multiple versions of the same class in the cluster sharign data.
0171:                    value = ObjectID.NULL_ID;
0172:                }
0173:
0174:                // final Class valueClass = value.getClass();
0175:                // final int type = literalValues.valueFor(valueClass.getName());
0176:                final int type = literalValues.valueFor(value);
0177:
0178:                switch (type) {
0179:                case LiteralValues.CURRENCY:
0180:                    output.writeByte(TYPE_ID_CURRENCY);
0181:                    writeString(((Currency) value).getCurrencyCode(), output);
0182:                    break;
0183:                case LiteralValues.ENUM:
0184:                    output.writeByte(TYPE_ID_ENUM);
0185:                    Class enumClass = getEnumDeclaringClass(value);
0186:                    writeString(enumClass.getName(), output);
0187:                    writeString(classProvider
0188:                            .getLoaderDescriptionFor(enumClass), output);
0189:
0190:                    Object name = getEnumName(value);
0191:                    writeString((String) name, output);
0192:                    break;
0193:                case LiteralValues.ENUM_HOLDER:
0194:                    output.writeByte(TYPE_ID_ENUM_HOLDER);
0195:                    writeEnumInstance((EnumInstance) value, output);
0196:                    break;
0197:                case LiteralValues.JAVA_LANG_CLASSLOADER:
0198:                    encodeClassLoader(value, output);
0199:                    break;
0200:                case LiteralValues.JAVA_LANG_CLASSLOADER_HOLDER:
0201:                    output.writeByte(TYPE_ID_JAVA_LANG_CLASSLOADER_HOLDER);
0202:                    writeClassLoaderInstance((ClassLoaderInstance) value,
0203:                            output);
0204:                    break;
0205:                case LiteralValues.JAVA_LANG_CLASS:
0206:                    output.writeByte(TYPE_ID_JAVA_LANG_CLASS);
0207:                    Class c = (Class) value;
0208:                    writeString(c.getName(), output);
0209:                    writeString(classProvider.getLoaderDescriptionFor(c),
0210:                            output);
0211:                    break;
0212:                case LiteralValues.JAVA_LANG_CLASS_HOLDER:
0213:                    output.writeByte(TYPE_ID_JAVA_LANG_CLASS_HOLDER);
0214:                    writeClassInstance((ClassInstance) value, output);
0215:                    break;
0216:                case LiteralValues.BOOLEAN:
0217:                    output.writeByte(TYPE_ID_BOOLEAN);
0218:                    output.writeBoolean(((Boolean) value).booleanValue());
0219:                    break;
0220:                case LiteralValues.BYTE:
0221:                    output.writeByte(TYPE_ID_BYTE);
0222:                    output.writeByte(((Byte) value).byteValue());
0223:                    break;
0224:                case LiteralValues.CHARACTER:
0225:                    output.writeByte(TYPE_ID_CHAR);
0226:                    output.writeChar(((Character) value).charValue());
0227:                    break;
0228:                case LiteralValues.DOUBLE:
0229:                    output.writeByte(TYPE_ID_DOUBLE);
0230:                    output.writeDouble(((Double) value).doubleValue());
0231:                    break;
0232:                case LiteralValues.FLOAT:
0233:                    output.writeByte(TYPE_ID_FLOAT);
0234:                    output.writeFloat(((Float) value).floatValue());
0235:                    break;
0236:                case LiteralValues.INTEGER:
0237:                    output.writeByte(TYPE_ID_INT);
0238:                    output.writeInt(((Integer) value).intValue());
0239:                    break;
0240:                case LiteralValues.LONG:
0241:                    output.writeByte(TYPE_ID_LONG);
0242:                    output.writeLong(((Long) value).longValue());
0243:                    break;
0244:                case LiteralValues.SHORT:
0245:                    output.writeByte(TYPE_ID_SHORT);
0246:                    output.writeShort(((Short) value).shortValue());
0247:                    break;
0248:                case LiteralValues.STRING:
0249:                    String s = (String) value;
0250:                    if (STRING_COMPRESSION_ENABLED
0251:                            && s.length() >= STRING_COMPRESSION_MIN_SIZE) {
0252:                        output.writeByte(TYPE_ID_STRING_COMPRESSED);
0253:                        writeCompressedString(s, output);
0254:                    } else {
0255:                        output.writeByte(TYPE_ID_STRING);
0256:                        writeString(s, output);
0257:                    }
0258:                    break;
0259:                case LiteralValues.STRING_BYTES:
0260:                    UTF8ByteDataHolder utfBytes = (UTF8ByteDataHolder) value;
0261:                    if (utfBytes.isCompressed()) {
0262:                        output.writeByte(TYPE_ID_STRING_COMPRESSED);
0263:                        output.writeInt(utfBytes.getUnCompressedStringLength());
0264:                        writeByteArray(utfBytes.getBytes(), output);
0265:                    } else {
0266:                        output.writeByte(TYPE_ID_STRING_BYTES);
0267:                        writeByteArray(utfBytes.getBytes(), output);
0268:                    }
0269:                    break;
0270:                case LiteralValues.OBJECT_ID:
0271:                    output.writeByte(TYPE_ID_REFERENCE);
0272:                    output.writeLong(((ObjectID) value).toLong());
0273:                    break;
0274:                case LiteralValues.STACK_TRACE_ELEMENT:
0275:                    output.writeByte(TYPE_ID_STACK_TRACE_ELEMENT);
0276:                    StackTraceElement ste = (StackTraceElement) value;
0277:                    writeStackTraceElement(ste, output);
0278:                    break;
0279:                case LiteralValues.BIG_INTEGER:
0280:                    output.writeByte(TYPE_ID_BIG_INTEGER);
0281:                    writeByteArray(((BigInteger) value).toByteArray(), output);
0282:                    break;
0283:                case LiteralValues.BIG_DECIMAL:
0284:                    output.writeByte(TYPE_ID_BIG_DECIMAL);
0285:                    writeByteArray(((BigDecimal) value).toString().getBytes(),
0286:                            output);
0287:                    break;
0288:                case LiteralValues.ARRAY:
0289:                    encodeArray(value, output);
0290:                    break;
0291:                //      case LiteralValues.URL:
0292:                //        {
0293:                //          URL url = (URL)value;
0294:                //          output.writeByte(TYPE_ID_URL);
0295:                //          output.writeString(url.getProtocol());
0296:                //          output.writeString(url.getHost());
0297:                //          output.writeInt(url.getPort());
0298:                //          output.writeString(url.getFile());
0299:                //          output.writeString(url.getRef());
0300:                //        }
0301:                //        break;
0302:                default:
0303:                    throw Assert
0304:                            .failure("Illegal type (" + type + "):" + value);
0305:                }
0306:
0307:                // unreachable
0308:            }
0309:
0310:            private void writeStackTraceElement(StackTraceElement ste,
0311:                    TCDataOutput output) {
0312:                output.writeString(ste.getClassName());
0313:                output.writeString(ste.getMethodName());
0314:                output.writeString(ste.getFileName());
0315:                output.writeInt(ste.getLineNumber());
0316:            }
0317:
0318:            private void writeEnumInstance(EnumInstance value,
0319:                    TCDataOutput output) {
0320:                writeByteArray(value.getClassInstance().getName().getBytes(),
0321:                        output);
0322:                writeByteArray(value.getClassInstance().getLoaderDef()
0323:                        .getBytes(), output);
0324:                writeByteArray(((UTF8ByteDataHolder) value.getEnumName())
0325:                        .getBytes(), output);
0326:            }
0327:
0328:            private void writeClassLoaderInstance(ClassLoaderInstance value,
0329:                    TCDataOutput output) {
0330:                writeByteArray(value.getLoaderDef().getBytes(), output);
0331:            }
0332:
0333:            private void writeClassInstance(ClassInstance value,
0334:                    TCDataOutput output) {
0335:                writeByteArray(value.getName().getBytes(), output);
0336:                writeByteArray(value.getLoaderDef().getBytes(), output);
0337:            }
0338:
0339:            private void writeString(String string, TCDataOutput output) {
0340:                try {
0341:                    writeByteArray(string.getBytes("UTF-8"), output);
0342:                } catch (UnsupportedEncodingException e) {
0343:                    throw new AssertionError(e);
0344:                }
0345:            }
0346:
0347:            private void writeCompressedString(String string,
0348:                    TCDataOutput output) {
0349:                try {
0350:                    TCByteArrayOutputStream byteArrayOS = new TCByteArrayOutputStream(
0351:                            4096);
0352:                    // Stride is 512 bytes by default, should I increase ?
0353:                    DeflaterOutputStream dos = new DeflaterOutputStream(
0354:                            byteArrayOS);
0355:                    byte[] uncompressed = string.getBytes("UTF-8");
0356:                    dos.write(uncompressed);
0357:                    dos.close();
0358:                    byte[] compressed = byteArrayOS.getInternalArray();
0359:                    // XXX:: We are writting the original string's length so that we save a couple of copies when decompressing
0360:                    output.writeInt(uncompressed.length);
0361:                    writeByteArray(compressed, 0, byteArrayOS.size(), output);
0362:                    if (STRING_COMPRESSION_LOGGING_ENABLED) {
0363:                        logger.info("Compressed String of size : "
0364:                                + string.length() + " bytes : "
0365:                                + uncompressed.length + " to  bytes : "
0366:                                + compressed.length);
0367:                    }
0368:                } catch (Exception e) {
0369:                    throw new AssertionError(e);
0370:                }
0371:            }
0372:
0373:            private void writeByteArray(byte[] bytes, int offset, int length,
0374:                    TCDataOutput output) {
0375:                output.writeInt(length);
0376:                output.write(bytes, offset, length);
0377:            }
0378:
0379:            private void writeByteArray(byte bytes[], TCDataOutput output) {
0380:                output.writeInt(bytes.length);
0381:                output.write(bytes);
0382:            }
0383:
0384:            /* This method is an optimized method for writing char array when no check is needed */
0385:            // private void writeCharArray(char[] chars, TCDataOutput output) {
0386:            // output.writeInt(chars.length);
0387:            // for (int i = 0, n = chars.length; i < n; i++) {
0388:            // output.writeChar(chars[i]);
0389:            // }
0390:            // }
0391:            private byte[] readByteArray(TCDataInput input) throws IOException {
0392:                int length = input.readInt();
0393:                if (length >= BYTE_WARN) {
0394:                    logger
0395:                            .warn("Attempting to allocate a large byte array of size: "
0396:                                    + length);
0397:                }
0398:                byte[] array = new byte[length];
0399:                input.readFully(array);
0400:                return array;
0401:            }
0402:
0403:            public Object decode(TCDataInput input) throws IOException,
0404:                    ClassNotFoundException {
0405:                final byte type = input.readByte();
0406:
0407:                switch (type) {
0408:                case TYPE_ID_CURRENCY:
0409:                    return readCurrency(input, type);
0410:                case TYPE_ID_ENUM:
0411:                    return readEnum(input, type);
0412:                case TYPE_ID_ENUM_HOLDER:
0413:                    return readEnum(input, type);
0414:                case TYPE_ID_JAVA_LANG_CLASSLOADER:
0415:                    return readClassLoader(input, type);
0416:                case TYPE_ID_JAVA_LANG_CLASSLOADER_HOLDER:
0417:                    return readClassLoader(input, type);
0418:                case TYPE_ID_JAVA_LANG_CLASS:
0419:                    return readClass(input, type);
0420:                case TYPE_ID_JAVA_LANG_CLASS_HOLDER:
0421:                    return readClass(input, type);
0422:                case TYPE_ID_BOOLEAN:
0423:                    return new Boolean(input.readBoolean());
0424:                case TYPE_ID_BYTE:
0425:                    return new Byte(input.readByte());
0426:                case TYPE_ID_CHAR:
0427:                    return new Character(input.readChar());
0428:                case TYPE_ID_DOUBLE:
0429:                    return new Double(input.readDouble());
0430:                case TYPE_ID_FLOAT:
0431:                    return new Float(input.readFloat());
0432:                case TYPE_ID_INT:
0433:                    return new Integer(input.readInt());
0434:                case TYPE_ID_LONG:
0435:                    return new Long(input.readLong());
0436:                case TYPE_ID_SHORT:
0437:                    return new Short(input.readShort());
0438:                case TYPE_ID_STRING:
0439:                    return readString(input, type);
0440:                case TYPE_ID_STRING_COMPRESSED:
0441:                    return readCompressedString(input);
0442:                case TYPE_ID_STRING_BYTES:
0443:                    return readString(input, type);
0444:                case TYPE_ID_REFERENCE:
0445:                    return new ObjectID(input.readLong());
0446:                case TYPE_ID_ARRAY:
0447:                    return decodeArray(input);
0448:                case TYPE_ID_STACK_TRACE_ELEMENT:
0449:                    return readStackTraceElement(input);
0450:                case TYPE_ID_BIG_INTEGER:
0451:                    byte[] b1 = readByteArray(input);
0452:                    return new BigInteger(b1);
0453:                case TYPE_ID_BIG_DECIMAL:
0454:                    // char[] chars = readCharArray(input); // Unfortunately this is 1.5 specific
0455:                    byte[] b2 = readByteArray(input);
0456:                    return new BigDecimal(new String(b2));
0457:                    //      case TYPE_ID_URL:
0458:                    //        {        
0459:                    //          String protocol = input.readString();
0460:                    //          String host = input.readString();
0461:                    //          int port = input.readInt();
0462:                    //          String file = input.readString();
0463:                    //          String ref = input.readString();
0464:                    //          if (ref != null) {
0465:                    //            file = file+"#"+ref;
0466:                    //          }
0467:                    //          return new URL(protocol, host, port, file);
0468:                    //        }
0469:                default:
0470:                    throw Assert.failure("Illegal type (" + type + ")");
0471:                }
0472:
0473:                // unreachable
0474:            }
0475:
0476:            // private char[] readCharArray(TCDataInput input) throws IOException {
0477:            // int length = input.readInt();
0478:            // if (length >= CHAR_WARN) {
0479:            // logger.warn("Attempting to allocate a large char array of size: " + length);
0480:            // }
0481:            // char[] array = new char[length];
0482:            // for (int i = 0, n = array.length; i < n; i++) {
0483:            // array[i] = input.readChar();
0484:            // }
0485:            // return array;
0486:            // }
0487:
0488:            private Object readStackTraceElement(TCDataInput input)
0489:                    throws IOException, ClassNotFoundException {
0490:                String className = input.readString();
0491:                String methodName = input.readString();
0492:                String fileName = input.readString();
0493:                int lineNumber = input.readInt();
0494:                return createStackTraceElement(className, fileName, methodName,
0495:                        lineNumber);
0496:            }
0497:
0498:            /*
0499:             * This method uses reflection as 1.4 doesnt have a public constructor for stack trace element and 1.5 removed the
0500:             * private no arg constructor. XXX::This is an ugly hack that I would like to getaway from
0501:             */
0502:            private Object createStackTraceElement(String className,
0503:                    String fileName, String methodName, int lineNumber)
0504:                    throws ClassNotFoundException, IOException {
0505:                Class clazz = Class.forName("java.lang.StackTraceElement");
0506:                Constructor constructors[] = clazz.getDeclaredConstructors();
0507:                for (int i = 0; i < constructors.length; i++) {
0508:                    Class[] types = constructors[i].getParameterTypes();
0509:                    if (types.length == 0) {
0510:                        // This is 1.4
0511:                        return createStackTraceElementJDK14(clazz,
0512:                                constructors[i], className, fileName,
0513:                                methodName, lineNumber);
0514:                    } else if (types.length == 4 && types[0] == String.class
0515:                            && types[1] == String.class
0516:                            && types[2] == String.class
0517:                            && types[3] == int.class) {
0518:                        // This is 1.5
0519:                        return createStackTraceElementJDK15(clazz,
0520:                                constructors[i], className, fileName,
0521:                                methodName, lineNumber);
0522:                    }
0523:                }
0524:                throw new ClassNotFoundException(
0525:                        "java.lang.StackTraceElement : Both known constructors not found !");
0526:            }
0527:
0528:            private Object createStackTraceElementJDK14(Class clazz,
0529:                    Constructor constructor, String className, String fileName,
0530:                    String methodName, int lineNumber) throws IOException {
0531:                try {
0532:                    constructor.setAccessible(true);
0533:                    Object i = constructor.newInstance(new Object[0]);
0534:                    Field[] fields = clazz.getDeclaredFields();
0535:                    byte set = 0x00;
0536:                    for (int j = 0; j < fields.length; j++) {
0537:                        fields[j].setAccessible(true);
0538:                        if ("declaringClass".equalsIgnoreCase(fields[j]
0539:                                .getName())) {
0540:                            fields[j].set(i, className);
0541:                            set |= 0x01;
0542:                        } else if ("methodName".equalsIgnoreCase(fields[j]
0543:                                .getName())) {
0544:                            fields[j].set(i, methodName);
0545:                            set |= 0x02;
0546:                        } else if ("fileName".equalsIgnoreCase(fields[j]
0547:                                .getName())) {
0548:                            fields[j].set(i, fileName);
0549:                            set |= 0x04;
0550:                        } else if ("lineNumber".equalsIgnoreCase(fields[j]
0551:                                .getName())) {
0552:                            fields[j].setInt(i, lineNumber);
0553:                            set |= 0x08;
0554:                        }
0555:                    }
0556:                    Assert.assertTrue(set == 0x0F);
0557:                    return i;
0558:                } catch (Exception ex) {
0559:                    IOException ioe = new IOException();
0560:                    ioe.initCause(ex);
0561:                    throw ioe;
0562:                }
0563:            }
0564:
0565:            private Object createStackTraceElementJDK15(Class clazz,
0566:                    Constructor constructor, String className, String fileName,
0567:                    String methodName, int lineNumber) throws IOException {
0568:                try {
0569:                    Object params[] = new Object[4];
0570:                    params[0] = className;
0571:                    params[1] = methodName;
0572:                    params[2] = fileName;
0573:                    params[3] = new Integer(lineNumber);
0574:                    return constructor.newInstance(params);
0575:                } catch (Exception ex) {
0576:                    IOException ioe = new IOException();
0577:                    ioe.initCause(ex);
0578:                    throw ioe;
0579:                }
0580:            }
0581:
0582:            public void encodeArray(Object value, TCDataOutput output) {
0583:                encodeArray(value, output, value == null ? -1 : Array
0584:                        .getLength(value));
0585:            }
0586:
0587:            public void encodeArray(Object value, TCDataOutput output,
0588:                    int length) {
0589:                output.writeByte(TYPE_ID_ARRAY);
0590:
0591:                if (value == null) {
0592:                    output.writeInt(-1);
0593:                    return;
0594:                } else {
0595:                    output.writeInt(length);
0596:                }
0597:
0598:                Class type = value.getClass().getComponentType();
0599:
0600:                if (type.isPrimitive()) {
0601:                    output.writeByte(ARRAY_TYPE_PRIMITIVE);
0602:                    switch (primitiveClassMap.get(type)) {
0603:                    case TYPE_ID_BOOLEAN:
0604:                        encodeBooleanArray((boolean[]) value, output, length);
0605:                        break;
0606:                    case TYPE_ID_BYTE:
0607:                        encodeByteArray((byte[]) value, output, length);
0608:                        break;
0609:                    case TYPE_ID_CHAR:
0610:                        encodeCharArray((char[]) value, output, length);
0611:                        break;
0612:                    case TYPE_ID_SHORT:
0613:                        encodeShortArray((short[]) value, output, length);
0614:                        break;
0615:                    case TYPE_ID_INT:
0616:                        encodeIntArray((int[]) value, output, length);
0617:                        break;
0618:                    case TYPE_ID_LONG:
0619:                        encodeLongArray((long[]) value, output, length);
0620:                        break;
0621:                    case TYPE_ID_FLOAT:
0622:                        encodeFloatArray((float[]) value, output, length);
0623:                        break;
0624:                    case TYPE_ID_DOUBLE:
0625:                        encodeDoubleArray((double[]) value, output, length);
0626:                        break;
0627:                    default:
0628:                        throw Assert.failure("unknown primitive array type: "
0629:                                + type);
0630:                    }
0631:                } else {
0632:                    output.writeByte(ARRAY_TYPE_NON_PRIMITIVE);
0633:                    encodeObjectArray((Object[]) value, output, length);
0634:                }
0635:            }
0636:
0637:            private void encodeByteArray(byte[] value, TCDataOutput output,
0638:                    int length) {
0639:                output.writeByte(TYPE_ID_BYTE);
0640:
0641:                for (int i = 0; i < length; i++) {
0642:                    output.write(value[i]);
0643:                }
0644:            }
0645:
0646:            private void encodeObjectArray(Object[] value, TCDataOutput output,
0647:                    int length) {
0648:                for (int i = 0; i < length; i++) {
0649:                    encode(value[i], output);
0650:                }
0651:            }
0652:
0653:            private void encodeDoubleArray(double[] value, TCDataOutput output,
0654:                    int length) {
0655:                output.writeByte(TYPE_ID_DOUBLE);
0656:                for (int i = 0; i < length; i++) {
0657:                    output.writeDouble(value[i]);
0658:                }
0659:            }
0660:
0661:            private void encodeFloatArray(float[] value, TCDataOutput output,
0662:                    int length) {
0663:                output.writeByte(TYPE_ID_FLOAT);
0664:                for (int i = 0; i < length; i++) {
0665:                    output.writeFloat(value[i]);
0666:                }
0667:            }
0668:
0669:            private void encodeLongArray(long[] value, TCDataOutput output,
0670:                    int length) {
0671:                output.writeByte(TYPE_ID_LONG);
0672:                for (int i = 0; i < length; i++) {
0673:                    output.writeLong(value[i]);
0674:                }
0675:            }
0676:
0677:            private void encodeIntArray(int[] value, TCDataOutput output,
0678:                    int length) {
0679:                output.writeByte(TYPE_ID_INT);
0680:                for (int i = 0; i < length; i++) {
0681:                    output.writeInt(value[i]);
0682:                }
0683:            }
0684:
0685:            private void encodeShortArray(short[] value, TCDataOutput output,
0686:                    int length) {
0687:                output.writeByte(TYPE_ID_SHORT);
0688:                for (int i = 0; i < length; i++) {
0689:                    output.writeShort(value[i]);
0690:                }
0691:            }
0692:
0693:            private void encodeCharArray(char[] value, TCDataOutput output,
0694:                    int length) {
0695:                output.writeByte(TYPE_ID_CHAR);
0696:                for (int i = 0; i < length; i++) {
0697:                    output.writeChar(value[i]);
0698:                }
0699:            }
0700:
0701:            private void encodeBooleanArray(boolean[] value,
0702:                    TCDataOutput output, int length) {
0703:                output.writeByte(TYPE_ID_BOOLEAN);
0704:                for (int i = 0; i < length; i++) {
0705:                    output.writeBoolean(value[i]);
0706:                }
0707:            }
0708:
0709:            private void checkSize(Class type, int threshold, int len) {
0710:                if (len >= threshold) {
0711:                    logger.warn("Attempt to read a " + type + " array of len: "
0712:                            + len + "; threshold=" + threshold);
0713:                }
0714:            }
0715:
0716:            private Object decodeArray(TCDataInput input) throws IOException,
0717:                    ClassNotFoundException {
0718:                final int len = input.readInt();
0719:                if (len < 0) {
0720:                    return null;
0721:                }
0722:
0723:                final byte arrayType = input.readByte();
0724:                switch (arrayType) {
0725:                case ARRAY_TYPE_PRIMITIVE:
0726:                    return decodePrimitiveArray(len, input);
0727:                case ARRAY_TYPE_NON_PRIMITIVE:
0728:                    return decodeNonPrimitiveArray(len, input);
0729:                default:
0730:                    throw Assert.failure("unknown array type: " + arrayType);
0731:                }
0732:
0733:                // unreachable
0734:            }
0735:
0736:            private Object[] decodeNonPrimitiveArray(int len, TCDataInput input)
0737:                    throws IOException, ClassNotFoundException {
0738:                checkSize(Object.class, REF_WARN, len);
0739:                Object[] rv = new Object[len];
0740:                for (int i = 0, n = rv.length; i < n; i++) {
0741:                    rv[i] = decode(input);
0742:                }
0743:
0744:                return rv;
0745:            }
0746:
0747:            private Object decodePrimitiveArray(int len, TCDataInput input)
0748:                    throws IOException {
0749:                byte type = input.readByte();
0750:
0751:                switch (type) {
0752:                case TYPE_ID_BOOLEAN:
0753:                    checkSize(Boolean.TYPE, BOOLEAN_WARN, len);
0754:                    return decodeBooleanArray(len, input);
0755:                case TYPE_ID_BYTE:
0756:                    checkSize(Byte.TYPE, BYTE_WARN, len);
0757:                    return decodeByteArray(len, input);
0758:                case TYPE_ID_CHAR:
0759:                    checkSize(Character.TYPE, CHAR_WARN, len);
0760:                    return decodeCharArray(len, input);
0761:                case TYPE_ID_DOUBLE:
0762:                    checkSize(Double.TYPE, DOUBLE_WARN, len);
0763:                    return decodeDoubleArray(len, input);
0764:                case TYPE_ID_FLOAT:
0765:                    checkSize(Float.TYPE, FLOAT_WARN, len);
0766:                    return decodeFloatArray(len, input);
0767:                case TYPE_ID_INT:
0768:                    checkSize(Integer.TYPE, INT_WARN, len);
0769:                    return decodeIntArray(len, input);
0770:                case TYPE_ID_LONG:
0771:                    checkSize(Long.TYPE, LONG_WARN, len);
0772:                    return decodeLongArray(len, input);
0773:                case TYPE_ID_SHORT:
0774:                    checkSize(Short.TYPE, SHORT_WARN, len);
0775:                    return decodeShortArray(len, input);
0776:                default:
0777:                    throw Assert.failure("unknown prim type: " + type);
0778:                }
0779:
0780:                // unreachable
0781:            }
0782:
0783:            private short[] decodeShortArray(int len, TCDataInput input)
0784:                    throws IOException {
0785:                short[] rv = new short[len];
0786:                for (int i = 0, n = rv.length; i < n; i++) {
0787:                    rv[i] = input.readShort();
0788:                }
0789:                return rv;
0790:            }
0791:
0792:            private long[] decodeLongArray(int len, TCDataInput input)
0793:                    throws IOException {
0794:                long[] rv = new long[len];
0795:                for (int i = 0, n = rv.length; i < n; i++) {
0796:                    rv[i] = input.readLong();
0797:                }
0798:                return rv;
0799:            }
0800:
0801:            private int[] decodeIntArray(int len, TCDataInput input)
0802:                    throws IOException {
0803:                int[] rv = new int[len];
0804:                for (int i = 0, n = rv.length; i < n; i++) {
0805:                    rv[i] = input.readInt();
0806:                }
0807:                return rv;
0808:            }
0809:
0810:            private float[] decodeFloatArray(int len, TCDataInput input)
0811:                    throws IOException {
0812:                float[] rv = new float[len];
0813:                for (int i = 0, n = rv.length; i < n; i++) {
0814:                    rv[i] = input.readFloat();
0815:                }
0816:                return rv;
0817:            }
0818:
0819:            private double[] decodeDoubleArray(int len, TCDataInput input)
0820:                    throws IOException {
0821:                double[] rv = new double[len];
0822:                for (int i = 0, n = rv.length; i < n; i++) {
0823:                    rv[i] = input.readDouble();
0824:                }
0825:                return rv;
0826:            }
0827:
0828:            private char[] decodeCharArray(int len, TCDataInput input)
0829:                    throws IOException {
0830:                char[] rv = new char[len];
0831:                for (int i = 0, n = rv.length; i < n; i++) {
0832:                    rv[i] = input.readChar();
0833:                }
0834:                return rv;
0835:            }
0836:
0837:            private byte[] decodeByteArray(int len, TCDataInput input)
0838:                    throws IOException {
0839:                byte[] rv = new byte[len];
0840:                if (len != 0) {
0841:                    int read = input.read(rv, 0, len);
0842:                    if (read != len) {
0843:                        throw new IOException("read " + read
0844:                                + " bytes, expected " + len);
0845:                    }
0846:                }
0847:                return rv;
0848:            }
0849:
0850:            private boolean[] decodeBooleanArray(int len, TCDataInput input)
0851:                    throws IOException {
0852:                boolean[] rv = new boolean[len];
0853:                for (int i = 0, n = rv.length; i < n; i++) {
0854:                    rv[i] = input.readBoolean();
0855:                }
0856:                return rv;
0857:            }
0858:
0859:            /**
0860:             * The reason that we use reflection here is because Enum is a jdk 1.5 construct and this project is jdk 1.4
0861:             * compliance.
0862:             */
0863:            private Class getEnumDeclaringClass(Object enumObj) {
0864:                try {
0865:                    Method m = enumObj.getClass().getMethod(
0866:                            "getDeclaringClass", new Class[0]);
0867:                    Object enumDeclaringClass = m
0868:                            .invoke(enumObj, new Object[0]);
0869:                    return (Class) enumDeclaringClass;
0870:                } catch (SecurityException e) {
0871:                    throw new TCRuntimeException(e);
0872:                } catch (NoSuchMethodException e) {
0873:                    throw new TCRuntimeException(e);
0874:                } catch (IllegalArgumentException e) {
0875:                    throw new TCRuntimeException(e);
0876:                } catch (IllegalAccessException e) {
0877:                    throw new TCRuntimeException(e);
0878:                } catch (InvocationTargetException e) {
0879:                    throw new TCRuntimeException(e);
0880:                }
0881:            }
0882:
0883:            /**
0884:             * The reason that we use reflection here is because Enum is a jdk 1.5 construct and this project is jdk 1.4
0885:             * compliance.
0886:             */
0887:            private Object enumValueOf(Class enumType, String enumName) {
0888:                try {
0889:                    Method m = enumType.getMethod("valueOf", new Class[] {
0890:                            Class.class, String.class });
0891:                    Object enumObj = m.invoke(null, new Object[] { enumType,
0892:                            enumName });
0893:                    return enumObj;
0894:                } catch (SecurityException e) {
0895:                    throw new TCRuntimeException(e);
0896:                } catch (NoSuchMethodException e) {
0897:                    throw new TCRuntimeException(e);
0898:                } catch (IllegalArgumentException e) {
0899:                    throw new TCRuntimeException(e);
0900:                } catch (IllegalAccessException e) {
0901:                    throw new TCRuntimeException(e);
0902:                } catch (InvocationTargetException e) {
0903:                    throw new TCRuntimeException(e);
0904:                }
0905:            }
0906:
0907:            private Object readCurrency(TCDataInput input, byte type)
0908:                    throws IOException {
0909:                byte[] data = readByteArray(input);
0910:                String currencyCode = new String(data, "UTF-8");
0911:                return Currency.getInstance(currencyCode);
0912:            }
0913:
0914:            private Object readEnum(TCDataInput input, byte type)
0915:                    throws IOException, ClassNotFoundException {
0916:                UTF8ByteDataHolder name = new UTF8ByteDataHolder(
0917:                        readByteArray(input));
0918:                UTF8ByteDataHolder def = new UTF8ByteDataHolder(
0919:                        readByteArray(input));
0920:                byte[] data = readByteArray(input);
0921:
0922:                if ((policy == SERIALIZER && type == TYPE_ID_ENUM)
0923:                        || policy == APPLICATOR) {
0924:                    Class enumType = new ClassInstance(name, def)
0925:                            .asClass(classProvider);
0926:
0927:                    String enumName = new String(data, "UTF-8");
0928:                    return enumValueOf(enumType, enumName);
0929:                } else {
0930:                    ClassInstance clazzInstance = new ClassInstance(name, def);
0931:                    UTF8ByteDataHolder enumName = new UTF8ByteDataHolder(data);
0932:                    return new EnumInstance(clazzInstance, enumName);
0933:                }
0934:            }
0935:
0936:            private Object readClassLoader(TCDataInput input, byte type)
0937:                    throws IOException {
0938:                UTF8ByteDataHolder def = new UTF8ByteDataHolder(
0939:                        readByteArray(input));
0940:
0941:                if ((policy == SERIALIZER && type == TYPE_ID_JAVA_LANG_CLASSLOADER)
0942:                        || policy == APPLICATOR) {
0943:                    return new ClassLoaderInstance(def)
0944:                            .asClassLoader(classProvider);
0945:                } else {
0946:                    return new ClassLoaderInstance(def);
0947:                }
0948:            }
0949:
0950:            private Object readClass(TCDataInput input, byte type)
0951:                    throws IOException, ClassNotFoundException {
0952:                UTF8ByteDataHolder name = new UTF8ByteDataHolder(
0953:                        readByteArray(input));
0954:                UTF8ByteDataHolder def = new UTF8ByteDataHolder(
0955:                        readByteArray(input));
0956:
0957:                if ((policy == SERIALIZER && type == TYPE_ID_JAVA_LANG_CLASS)
0958:                        || policy == APPLICATOR) {
0959:                    return new ClassInstance(name, def).asClass(classProvider);
0960:                } else {
0961:                    return new ClassInstance(name, def);
0962:                }
0963:            }
0964:
0965:            private Object readString(TCDataInput input, byte type)
0966:                    throws IOException {
0967:                byte[] data = readByteArray(input);
0968:                if ((policy == SERIALIZER && type == TYPE_ID_STRING)
0969:                        || policy == APPLICATOR) {
0970:                    return new String(data, "UTF-8");
0971:                } else {
0972:                    return new UTF8ByteDataHolder(data);
0973:                }
0974:            }
0975:
0976:            private Object readCompressedString(TCDataInput input)
0977:                    throws IOException {
0978:                int stringLength = input.readInt();
0979:                byte[] data = readByteArray(input);
0980:                if (policy == APPLICATOR) {
0981:                    return inflateCompressedString(data, stringLength);
0982:                } else {
0983:                    UTF8ByteDataHolder utfBytes = new UTF8ByteDataHolder(data,
0984:                            stringLength);
0985:                    return utfBytes;
0986:                }
0987:            }
0988:
0989:            public static String inflateCompressedString(byte[] data, int length) {
0990:                try {
0991:                    ByteArrayInputStream bais = new ByteArrayInputStream(data);
0992:                    InflaterInputStream iis = new InflaterInputStream(bais);
0993:                    byte uncompressed[] = new byte[length];
0994:                    int read;
0995:                    int offset = 0;
0996:                    while (length > 0
0997:                            && (read = iis.read(uncompressed, offset, length)) != -1) {
0998:                        offset += read;
0999:                        length -= read;
1000:                    }
1001:                    iis.close();
1002:                    Assert.assertEquals(0, length);
1003:                    return new String(uncompressed, "UTF-8");
1004:                } catch (IOException e) {
1005:                    throw new AssertionError(e);
1006:                }
1007:            }
1008:
1009:            private static class FailureClassProvider implements  ClassProvider {
1010:
1011:                public Class getClassFor(String className, String loaderDesc) {
1012:                    throw new AssertionError();
1013:                }
1014:
1015:                public String getLoaderDescriptionFor(Class clazz) {
1016:                    throw new AssertionError();
1017:                }
1018:
1019:                public ClassLoader getClassLoader(String loaderDesc) {
1020:                    throw new AssertionError();
1021:                }
1022:
1023:                public String getLoaderDescriptionFor(ClassLoader loader) {
1024:                    throw new AssertionError();
1025:                }
1026:
1027:                public void registerNamedLoader(NamedClassLoader loader) {
1028:                    throw new AssertionError();
1029:                }
1030:            }
1031:
1032:            private static class LocalClassProvider implements  ClassProvider {
1033:
1034:                private static final String LOADER_ID = LocalClassProvider.class
1035:                        .getName()
1036:                        + "::CLASSPROVIDER";
1037:
1038:                // This method assumes the Class is visible in this VM and can be loaded by the same class loader as this
1039:                // object. Only used in SERIALIZER policy
1040:                public Class getClassFor(String className, String loaderDesc) {
1041:                    Assert.assertEquals(LOADER_ID, loaderDesc);
1042:                    try {
1043:                        return Class.forName(className);
1044:                    } catch (ClassNotFoundException e) {
1045:                        throw new AssertionError(e);
1046:                    }
1047:                }
1048:
1049:                public String getLoaderDescriptionFor(Class clazz) {
1050:                    return LOADER_ID;
1051:                }
1052:
1053:                public ClassLoader getClassLoader(String loaderDesc) {
1054:                    Assert.assertEquals(LOADER_ID, loaderDesc);
1055:                    return ClassLoader.getSystemClassLoader();
1056:                }
1057:
1058:                public String getLoaderDescriptionFor(ClassLoader loader) {
1059:                    return LOADER_ID;
1060:                }
1061:
1062:                public void registerNamedLoader(NamedClassLoader loader) {
1063:                    // do nothing
1064:                }
1065:            }
1066:
1067:            private static final TObjectIntHashMap primitiveClassMap = new TObjectIntHashMap();
1068:
1069:            static {
1070:                primitiveClassMap.put(java.lang.Boolean.TYPE, TYPE_ID_BOOLEAN);
1071:                primitiveClassMap.put(java.lang.Byte.TYPE, TYPE_ID_BYTE);
1072:                primitiveClassMap.put(java.lang.Character.TYPE, TYPE_ID_CHAR);
1073:                primitiveClassMap.put(java.lang.Double.TYPE, TYPE_ID_DOUBLE);
1074:                primitiveClassMap.put(java.lang.Float.TYPE, TYPE_ID_FLOAT);
1075:                primitiveClassMap.put(java.lang.Integer.TYPE, TYPE_ID_INT);
1076:                primitiveClassMap.put(java.lang.Long.TYPE, TYPE_ID_LONG);
1077:                primitiveClassMap.put(java.lang.Short.TYPE, TYPE_ID_SHORT);
1078:            }
1079:
1080:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.