1   /*
2    * Copyright (C) The MetaClass Group. All rights reserved.
3    *
4    * This software is published under the terms of the Spice
5    * Software License version 1.1, a copy of which has been included
6    * with this distribution in the LICENSE.txt file.
7    */
8   package org.codehaus.metaclass.io;
9   
10  import java.io.ByteArrayInputStream;
11  import java.io.ByteArrayOutputStream;
12  import java.io.DataInputStream;
13  import java.io.DataOutputStream;
14  import java.io.File;
15  import java.io.IOException;
16  import java.util.Properties;
17  import junit.framework.TestCase;
18  import org.codehaus.metaclass.model.Attribute;
19  import org.codehaus.metaclass.model.ClassDescriptor;
20  import org.codehaus.metaclass.model.FieldDescriptor;
21  import org.codehaus.metaclass.model.MethodDescriptor;
22  import org.codehaus.metaclass.model.ParameterDescriptor;
23  
24  /***
25   * @author Peter Donald
26   * @version $Revision: 1.23 $ $Date: 2003/12/11 08:41:51 $
27   */
28  public class MetaClassIOBinaryTestCase
29      extends TestCase
30  {
31      private static final int STRING_HEADER_SIZE = 2;
32  
33      public void testFailToSerialize()
34          throws Exception
35      {
36  
37          final ClassDescriptor descriptor =
38              new ClassDescriptor( "com.biz.Foo",
39                                   Attribute.EMPTY_SET,
40                                   Attribute.EMPTY_SET,
41                                   FieldDescriptor.EMPTY_SET,
42                                   MethodDescriptor.EMPTY_SET );
43          final File base = generateDirectory();
44          final FailingMetaClasIOBinary io = new FailingMetaClasIOBinary();
45          final String filename = io.getResourceName( descriptor.getName() );
46          final File file = new File( base, filename ).getCanonicalFile();
47          try
48          {
49              io.writeDescriptor( base, descriptor );
50          }
51          catch( final Exception e )
52          {
53              assertTrue( "!file.exists()", !file.exists() );
54              return;
55          }
56          fail( "Expected to fail to do IO" );
57      }
58  
59      public void testGetResourceName()
60          throws Exception
61      {
62          final MetaClassIOBinary io = new MetaClassIOBinary();
63          final String name = io.getResourceName( "Foo" );
64          assertEquals( "name", "Foo-meta.binary", name );
65      }
66  
67      public void testBinaryIOWriteZeroAttributes()
68          throws Exception
69      {
70          final MetaClassIOBinary io = new MetaClassIOBinary();
71          final ByteArrayOutputStream out = new ByteArrayOutputStream();
72          final DataOutputStream data = new DataOutputStream( out );
73          io.writeAttributes( data, Attribute.EMPTY_SET );
74          data.flush();
75          final byte[] bytes = out.toByteArray();
76          assertEquals( "length", 4, bytes.length );
77          assertEquals( "bytes[0-4] = 0", 0, readInteger( bytes, 0 ) );
78      }
79  
80      public void testBinaryIOReadZeroAttributes()
81          throws Exception
82      {
83          final byte[] bytes = new byte[]
84          {
85              0, 0, 0, 0 //length
86          };
87          final MetaClassIOBinary io = new MetaClassIOBinary();
88          final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
89          final DataInputStream data = new DataInputStream( in );
90          final Attribute[] attributes = io.readAttributes( data );
91          assertEquals( "attributes.length", 0, attributes.length );
92      }
93  
94      public void testBinaryIOWriteAttributeWithoutValueOrParameters()
95          throws Exception
96      {
97          final MetaClassIOBinary io = new MetaClassIOBinary();
98          final ByteArrayOutputStream out = new ByteArrayOutputStream();
99          final DataOutputStream data = new DataOutputStream( out );
100         final String name = "mx.attribute";
101         final Attribute attribute = new Attribute( name );
102         io.writeAttributes( data, new Attribute[]{attribute} );
103         data.flush();
104         final byte[] bytes = out.toByteArray();
105         assertEquals( "length", 24, bytes.length );
106         int offset = 0;
107         assertEquals( "bytes[" + offset + "] = 1",
108                       1,
109                       readInteger( bytes, offset ) );
110         offset = 4;
111         assertEquals( "bytes[" + offset + "] = " + name,
112                       name,
113                       readString( bytes, offset ) );
114         offset += STRING_HEADER_SIZE + name.length();
115         assertEquals( "bytes[" + offset + "] = " + "''",
116                       "",
117                       readString( bytes, offset ) );
118         offset += STRING_HEADER_SIZE;
119         assertEquals( "bytes[" + offset + "] = 0",
120                       0,
121                       readInteger( bytes, offset ) );
122     }
123 
124     public void testBinaryIOReadAttributeWithoutValueOrParameters()
125         throws Exception
126     {
127         final String name = "name";
128         final String value = null;
129         final int paramCount = 0;
130         final byte[] bytes = new byte[]
131         {
132             0, 0, 0, 1, //length
133             0, 4, //length of name
134             'n', 'a', 'm', 'e',
135             0, 0, //length of value
136             0, 0, 0, 0 //count of params
137 
138         };
139         final MetaClassIOBinary io = new MetaClassIOBinary();
140         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
141         final DataInputStream data = new DataInputStream( in );
142         final Attribute[] attributes = io.readAttributes( data );
143         assertEquals( "attributes.length", 1, attributes.length );
144         assertEquals( "attributes[0].name", name, attributes[ 0 ].getName() );
145         assertEquals( "attributes[0].value",
146                       value,
147                       attributes[ 0 ].getValue() );
148         assertEquals( "attributes[0].parameterCount",
149                       paramCount,
150                       attributes[ 0 ].getParameterCount() );
151     }
152 
153     public void testBinaryIOWriteAttributeWithValue()
154         throws Exception
155     {
156         final MetaClassIOBinary io = new MetaClassIOBinary();
157         final ByteArrayOutputStream out = new ByteArrayOutputStream();
158         final DataOutputStream data = new DataOutputStream( out );
159         final String name = "mx.attribute";
160         final String value = "This is an attribute";
161         final Attribute attribute = new Attribute( name, value );
162         io.writeAttributes( data, new Attribute[]{attribute} );
163         data.flush();
164         final byte[] bytes = out.toByteArray();
165         assertEquals( "length", 44, bytes.length );
166         int offset = 0;
167         assertEquals( "bytes[" + offset + "] = 1",
168                       1,
169                       readInteger( bytes, offset ) );
170         offset = 4;
171         assertEquals( "bytes[" + offset + "] = " + name,
172                       name,
173                       readString( bytes, offset ) );
174         offset += STRING_HEADER_SIZE + name.length();
175         assertEquals( "bytes[" + offset + "] = " + value,
176                       value,
177                       readString( bytes, offset ) );
178         offset += STRING_HEADER_SIZE + value.length();
179         assertEquals( "bytes[" + offset + "] = 0",
180                       0,
181                       readInteger( bytes, offset ) );
182     }
183 
184     public void testBinaryIOReadAttributeWithValueAndParameters()
185         throws Exception
186     {
187         final byte[] bytes = new byte[]
188         {
189             0, 0, 0, 1, //length
190             0, 4, //length of name
191             'n', 'a', 'm', 'e',
192             0, 6, //length of value
193             'a', 'V', 'a', 'l', 'u', 'e',
194             0, 0, 0, 1, //count of params
195             0, 3, //length of paramKey
196             'k', 'e', 'y',
197             0, 5, //length of paramKey
198             'v', 'a', 'l', 'u', 'e'
199 
200         };
201         final MetaClassIOBinary io = new MetaClassIOBinary();
202         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
203         final DataInputStream data = new DataInputStream( in );
204         try
205         {
206             io.readAttributes( data );
207         }
208         catch( IOException ioe )
209         {
210             return;
211         }
212         fail( "Expected to fail reading attributes with value and parameters" );
213     }
214 
215     public void testBinaryIOReadAttributeWithValue()
216         throws Exception
217     {
218         final String name = "name";
219         final String value = "aValue";
220         final int paramCount = 0;
221         final byte[] bytes = new byte[]
222         {
223             0, 0, 0, 1, //length
224             0, 4, //length of name
225             'n', 'a', 'm', 'e',
226             0, 6, //length of value
227             'a', 'V', 'a', 'l', 'u', 'e',
228             0, 0, 0, 0 //count of params
229 
230         };
231         final MetaClassIOBinary io = new MetaClassIOBinary();
232         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
233         final DataInputStream data = new DataInputStream( in );
234         final Attribute[] attributes = io.readAttributes( data );
235         assertEquals( "attributes.length", 1, attributes.length );
236         assertEquals( "attributes[0].name", name, attributes[ 0 ].getName() );
237         assertEquals( "attributes[0].value",
238                       value,
239                       attributes[ 0 ].getValue() );
240         assertEquals( "attributes[0].parameterCount",
241                       paramCount,
242                       attributes[ 0 ].getParameterCount() );
243     }
244 
245     public void testBinaryIOWriteAttributeWithParameters()
246         throws Exception
247     {
248         final MetaClassIOBinary io = new MetaClassIOBinary();
249         final ByteArrayOutputStream out = new ByteArrayOutputStream();
250         final DataOutputStream data = new DataOutputStream( out );
251         final String name = "mx.attribute";
252 
253         final Properties parameters = new Properties();
254         final String paramKey = "magic";
255         final String paramValue = "lots";
256         parameters.setProperty( paramKey, paramValue );
257         final Attribute attribute = new Attribute( name, parameters );
258         io.writeAttributes( data, new Attribute[]{attribute} );
259         data.flush();
260         final byte[] bytes = out.toByteArray();
261         assertEquals( "length", 37, bytes.length );
262         int offset = 0;
263         assertEquals( "bytes[" + offset + "] = 1",
264                       1,
265                       readInteger( bytes, offset ) );
266         offset = 4;
267         assertEquals( "bytes[" + offset + "] = " + name,
268                       name,
269                       readString( bytes, offset ) );
270         offset += STRING_HEADER_SIZE + name.length();
271         assertEquals( "bytes[" + offset + "] = " + "''",
272                       "",
273                       readString( bytes, offset ) );
274         offset += STRING_HEADER_SIZE;
275         assertEquals( "bytes[" + offset + "] = 1",
276                       1,
277                       readInteger( bytes, offset ) );
278         offset += 4;
279         assertEquals( "bytes[" + offset + "] = " + paramKey,
280                       paramKey,
281                       readString( bytes, offset ) );
282         offset += STRING_HEADER_SIZE + paramKey.length();
283         assertEquals( "bytes[" + offset + "] = " + paramValue,
284                       paramValue,
285                       readString( bytes, offset ) );
286     }
287 
288     public void testBinaryIOReadAttributeWithParameters()
289         throws Exception
290     {
291         final String name = "name";
292         final String value = null;
293         final int paramCount = 1;
294         final String paramKey = "key";
295         final String paramValue = "value";
296         final byte[] bytes = new byte[]
297         {
298             0, 0, 0, 1, //length
299             0, 4, //length of name
300             'n', 'a', 'm', 'e',
301             0, 0, //length of value
302             0, 0, 0, 1, //count of params
303             0, 3, //length of paramKey
304             'k', 'e', 'y',
305             0, 5, //length of paramKey
306             'v', 'a', 'l', 'u', 'e'
307         };
308         final MetaClassIOBinary io = new MetaClassIOBinary();
309         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
310         final DataInputStream data = new DataInputStream( in );
311         final Attribute[] attributes = io.readAttributes( data );
312         assertEquals( "attributes.length", 1, attributes.length );
313         assertEquals( "attributes[0].name", name, attributes[ 0 ].getName() );
314         assertEquals( "attributes[0].value",
315                       value,
316                       attributes[ 0 ].getValue() );
317         assertEquals( "attributes[0].parameterCount",
318                       paramCount,
319                       attributes[ 0 ].getParameterCount() );
320         assertEquals( "attributes[0].parameter(key)",
321                       paramValue,
322                       attributes[ 0 ].getParameter( paramKey ) );
323     }
324 
325     public void testBinaryIOWriteParameters()
326         throws Exception
327     {
328         final MetaClassIOBinary io = new MetaClassIOBinary();
329         final ByteArrayOutputStream out = new ByteArrayOutputStream();
330         final DataOutputStream data = new DataOutputStream( out );
331         final String name = "name";
332         final String type = "aType";
333         final ParameterDescriptor descriptor = new ParameterDescriptor( name,
334                                                                         type );
335         io.writeParameters( data, new ParameterDescriptor[]{descriptor} );
336         data.flush();
337         final byte[] bytes = out.toByteArray();
338         assertEquals( "length", 17, bytes.length );
339         int offset = 0;
340         assertEquals( "bytes[" + offset + "] = 1",
341                       1,
342                       readInteger( bytes, offset ) );
343         offset = 4;
344         assertEquals( "bytes[" + offset + "] = " + name,
345                       name,
346                       readString( bytes, offset ) );
347         offset += STRING_HEADER_SIZE + name.length();
348         assertEquals( "bytes[" + offset + "] = " + type,
349                       type,
350                       readString( bytes, offset ) );
351         offset += STRING_HEADER_SIZE + type.length();
352     }
353 
354     public void testBinaryIOReadParameters()
355         throws Exception
356     {
357         final String name = "name";
358         final String type = "type";
359         final byte[] bytes = new byte[]
360         {
361             0, 0, 0, 1, //length
362             0, 4, //length of name
363             'n', 'a', 'm', 'e',
364             0, 4, //length of type
365             't', 'y', 'p', 'e'
366         };
367         final MetaClassIOBinary io = new MetaClassIOBinary();
368         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
369         final DataInputStream data = new DataInputStream( in );
370         final ParameterDescriptor[] parameters = io.readParameters( data );
371         assertEquals( "parameters.length", 1, parameters.length );
372         assertEquals( "parameters[0].name", name, parameters[ 0 ].getName() );
373         assertEquals( "parameters[0].type", type, parameters[ 0 ].getType() );
374     }
375 
376     public void testBinaryIOWriteZeroParameters()
377         throws Exception
378     {
379         final MetaClassIOBinary io = new MetaClassIOBinary();
380         final ByteArrayOutputStream out = new ByteArrayOutputStream();
381         final DataOutputStream data = new DataOutputStream( out );
382         io.writeParameters( data, ParameterDescriptor.EMPTY_SET );
383         data.flush();
384         final byte[] bytes = out.toByteArray();
385         assertEquals( "length", 4, bytes.length );
386         assertEquals( "bytes[0-4] = 0", 0, readInteger( bytes, 0 ) );
387     }
388 
389     public void testBinaryIOReadZeroParameters()
390         throws Exception
391     {
392         final byte[] bytes = new byte[]
393         {
394             0, 0, 0, 0 //length
395         };
396         final MetaClassIOBinary io = new MetaClassIOBinary();
397         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
398         final DataInputStream data = new DataInputStream( in );
399         final ParameterDescriptor[] parameters = io.readParameters( data );
400         assertEquals( "parameters.length", 0, parameters.length );
401     }
402 
403     public void testBinaryIOReadFields()
404         throws Exception
405     {
406         final String name = "name";
407         final String type = "type";
408         final int attributeCount = 0;
409         final byte[] bytes = new byte[]
410         {
411             0, 0, 0, 1, //length
412             0, 4, //length of name
413             'n', 'a', 'm', 'e',
414             0, 4, //length of type
415             't', 'y', 'p', 'e',
416             0, 0, 0, 0 //attribute count
417         };
418         final MetaClassIOBinary io = new MetaClassIOBinary();
419         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
420         final DataInputStream data = new DataInputStream( in );
421         final FieldDescriptor[] fields = io.readFields( data );
422         assertEquals( "fields.length", 1, fields.length );
423         assertEquals( "fields[0].name", name, fields[ 0 ].getName() );
424         assertEquals( "fields[0].type", type, fields[ 0 ].getType() );
425         assertEquals( "fields[0].attributes.length",
426                       attributeCount, fields[ 0 ].getAttributes().length );
427     }
428 
429     public void testBinaryIOWriteFields()
430         throws Exception
431     {
432         final MetaClassIOBinary io = new MetaClassIOBinary();
433         final ByteArrayOutputStream out = new ByteArrayOutputStream();
434         final DataOutputStream data = new DataOutputStream( out );
435         final String name = "name";
436         final String type = "aType";
437         final FieldDescriptor descriptor =
438             new FieldDescriptor( name,
439                                  type,
440                                  Attribute.EMPTY_SET,
441                                  Attribute.EMPTY_SET );
442         io.writeFields( data, new FieldDescriptor[]{descriptor} );
443         data.flush();
444         final byte[] bytes = out.toByteArray();
445         assertEquals( "length", 21, bytes.length );
446         int offset = 0;
447         assertEquals( "bytes[" + offset + "] = 1",
448                       1,
449                       readInteger( bytes, offset ) );
450         offset = 4;
451         assertEquals( "bytes[" + offset + "] = " + name,
452                       name,
453                       readString( bytes, offset ) );
454         offset += STRING_HEADER_SIZE + name.length();
455         assertEquals( "bytes[" + offset + "] = " + type,
456                       type,
457                       readString( bytes, offset ) );
458         offset += STRING_HEADER_SIZE + type.length();
459         assertEquals( "bytes[" + offset + "] = " + Attribute.EMPTY_SET.length,
460                       Attribute.EMPTY_SET.length,
461                       readInteger( bytes, offset ) );
462         offset += 4;
463     }
464 
465     public void testBinaryIOWriteZeroFields()
466         throws Exception
467     {
468         final MetaClassIOBinary io = new MetaClassIOBinary();
469         final ByteArrayOutputStream out = new ByteArrayOutputStream();
470         final DataOutputStream data = new DataOutputStream( out );
471         io.writeFields( data, FieldDescriptor.EMPTY_SET );
472         data.flush();
473         final byte[] bytes = out.toByteArray();
474         assertEquals( "length", 4, bytes.length );
475         assertEquals( "bytes[0-4] = 0", 0, readInteger( bytes, 0 ) );
476     }
477 
478     public void testBinaryIOReadZeroFields()
479         throws Exception
480     {
481         final byte[] bytes = new byte[]
482         {
483             0, 0, 0, 0 //length
484         };
485         final MetaClassIOBinary io = new MetaClassIOBinary();
486         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
487         final DataInputStream data = new DataInputStream( in );
488         final FieldDescriptor[] fields = io.readFields( data );
489         assertEquals( "fields.length", 0, fields.length );
490     }
491 
492     public void testBinaryIOReadMethods()
493         throws Exception
494     {
495         final String name = "name";
496         final String type = "type";
497         final int parameterCount = 0;
498         final int attributeCount = 0;
499         final byte[] bytes = new byte[]
500         {
501             0, 0, 0, 1, //length
502             0, 4, //length of name
503             'n', 'a', 'm', 'e',
504             0, 4, //length of return type
505             't', 'y', 'p', 'e',
506             0, 0, 0, 0, //parameter count
507             0, 0, 0, 0 //attribute count
508         };
509         final MetaClassIOBinary io = new MetaClassIOBinary();
510         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
511         final DataInputStream data = new DataInputStream( in );
512         final MethodDescriptor[] methods = io.readMethods( data );
513         assertEquals( "methods.length", 1, methods.length );
514         assertEquals( "methods[0].name", name, methods[ 0 ].getName() );
515         assertEquals( "methods[0].returnType",
516                       type,
517                       methods[ 0 ].getReturnType() );
518         assertEquals( "methods[0].attributes.length",
519                       attributeCount, methods[ 0 ].getAttributes().length );
520         assertEquals( "methods[0].attributes.length",
521                       parameterCount, methods[ 0 ].getParameters().length );
522     }
523 
524     public void testBinaryIOWriteMethods()
525         throws Exception
526     {
527         final MetaClassIOBinary io = new MetaClassIOBinary();
528         final ByteArrayOutputStream out = new ByteArrayOutputStream();
529         final DataOutputStream data = new DataOutputStream( out );
530         final String name = "name";
531         final String type = "aType";
532         final MethodDescriptor descriptor =
533             new MethodDescriptor( name,
534                                   type,
535                                   ParameterDescriptor.EMPTY_SET,
536                                   Attribute.EMPTY_SET, Attribute.EMPTY_SET );
537         io.writeMethods( data, new MethodDescriptor[]{descriptor} );
538         data.flush();
539         final byte[] bytes = out.toByteArray();
540         assertEquals( "length", 25, bytes.length );
541         int offset = 0;
542         assertEquals( "bytes[" + offset + "] = 1",
543                       1,
544                       readInteger( bytes, offset ) );
545         offset = 4;
546         assertEquals( "bytes[" + offset + "] = " + name,
547                       name,
548                       readString( bytes, offset ) );
549         offset += STRING_HEADER_SIZE + name.length();
550         assertEquals( "bytes[" + offset + "] = " + type,
551                       type,
552                       readString( bytes, offset ) );
553         offset += STRING_HEADER_SIZE + type.length();
554         assertEquals(
555             "bytes[" + offset + "] = " + ParameterDescriptor.EMPTY_SET.length,
556             ParameterDescriptor.EMPTY_SET.length,
557             readInteger( bytes, offset ) );
558         offset += 4;
559         assertEquals( "bytes[" + offset + "] = " + Attribute.EMPTY_SET.length,
560                       Attribute.EMPTY_SET.length,
561                       readInteger( bytes, offset ) );
562         offset += 4;
563     }
564 
565     public void testBinaryIOWriteZeroMethods()
566         throws Exception
567     {
568         final MetaClassIOBinary io = new MetaClassIOBinary();
569         final ByteArrayOutputStream out = new ByteArrayOutputStream();
570         final DataOutputStream data = new DataOutputStream( out );
571         io.writeMethods( data, MethodDescriptor.EMPTY_SET );
572         data.flush();
573         final byte[] bytes = out.toByteArray();
574         assertEquals( "length", 4, bytes.length );
575         assertEquals( "bytes[0-4] = 0", 0, readInteger( bytes, 0 ) );
576     }
577 
578     public void testBinaryIOReadZeroMethods()
579         throws Exception
580     {
581         final byte[] bytes = new byte[]
582         {
583             0, 0, 0, 0 //length
584         };
585         final MetaClassIOBinary io = new MetaClassIOBinary();
586         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
587         final DataInputStream data = new DataInputStream( in );
588         final MethodDescriptor[] methods = io.readMethods( data );
589         assertEquals( "methods.length", 0, methods.length );
590     }
591 
592     public void testBinaryIOWriteRead()
593         throws Exception
594     {
595         final Properties parameters = new Properties();
596         parameters.setProperty( "column", "field" );
597         final Attribute paramAttribute =
598             new Attribute( "persist", parameters );
599         final Attribute valueAttribute =
600             new Attribute( "mx.attribute", "This is an attribute" );
601         final Attribute[] attributes = new Attribute[]{valueAttribute,
602                                                        paramAttribute};
603         final FieldDescriptor field =
604             new FieldDescriptor( "m_field",
605                                  "int",
606                                  attributes,
607                                  attributes );
608         final MethodDescriptor method =
609             new MethodDescriptor( "doMagic",
610                                   "",
611                                   ParameterDescriptor.EMPTY_SET,
612                                   Attribute.EMPTY_SET,
613                                   Attribute.EMPTY_SET );
614         final ClassDescriptor descriptor =
615             new ClassDescriptor( "com.biz.MyClass",
616                                  Attribute.EMPTY_SET,
617                                  Attribute.EMPTY_SET,
618                                  new FieldDescriptor[]{field},
619                                  new MethodDescriptor[]{method} );
620         final MetaClassIOBinary io = new MetaClassIOBinary();
621         final ByteArrayOutputStream out = new ByteArrayOutputStream();
622         io.serializeClass( out, descriptor );
623 
624         final ByteArrayInputStream in = new ByteArrayInputStream(
625             out.toByteArray() );
626         io.deserializeClass( in );
627     }
628 
629     public void testBinaryIOReadClassWithBadVersion()
630         throws Exception
631     {
632         final byte[] bytes = new byte[]
633         {
634             'd', 'e', 'a', 'd', //bad version
635             0, 4, //length of classname
636             'n', 'a', 'm', 'e',
637             0, 0, 0, 0, //modifiers
638             0, 0, 0, 0, //attribute count
639             0, 0, 0, 0, //field count
640             0, 0, 0, 0 //method count
641         };
642         final MetaClassIOBinary io = new MetaClassIOBinary();
643         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
644         try
645         {
646             io.deserializeClass( in );
647         }
648         catch( IOException ioe )
649         {
650             //expect version mis match
651             return;
652         }
653         fail(
654             "Expected to fail reading descriptor as it has the wrong version" );
655     }
656 
657     public void testBinaryIOReadClass()
658         throws Exception
659     {
660         final String name = "name";
661         final int attributeCount = 0;
662         final byte[] bytes = new byte[]
663         {
664             0, 0, 0, 2, //version
665             0, 4, //length of package name
666             'n', 'a', 'm', 'e',
667             0, 0, 0, 0, //modifers
668             0, 0, 0, 0, //attribute count
669             0, 0, 0, 0, //field count
670             0, 0, 0, 0 //method count
671         };
672         final MetaClassIOBinary io = new MetaClassIOBinary();
673         final ByteArrayInputStream in = new ByteArrayInputStream( bytes );
674         final ClassDescriptor clazz = io.deserializeClass( in );
675         assertEquals( "class.name", name, clazz.getName() );
676         assertEquals( "class.attributes.length",
677                       attributeCount, clazz.getAttributes().length );
678         assertEquals( "class.methods.length",
679                       0, clazz.getMethods().length );
680         assertEquals( "class.fields.length",
681                       0, clazz.getFields().length );
682     }
683 
684     private int readShort( final byte[] data, final int offset )
685     {
686         return (
687                    ( ( data[ offset + 1 ] & 0xff ) << 0 ) +
688             ( ( data[ offset + 0 ] & 0xff ) << 8 ) );
689     }
690 
691     private int readInteger( final byte[] data, final int offset )
692     {
693         return (
694                    ( ( data[ offset + 3 ] & 0xff ) << 0 ) +
695             ( ( data[ offset + 2 ] & 0xff ) << 8 ) +
696             ( ( data[ offset + 1 ] & 0xff ) << 16 ) +
697             ( ( data[ offset + 0 ] & 0xff ) << 24 ) );
698     }
699 
700     private String readString( final byte[] data, final int offset )
701     {
702         final int count = readShort( data, offset );
703         return new String( data, offset + STRING_HEADER_SIZE, count );
704     }
705 
706     /***
707      * Method during test development to output array contents.
708      *
709      * @param bytes the byte array
710      */
711     protected final void outputArray( final byte[] bytes )
712     {
713         outputArrayAsInts( bytes );
714         outputArrayAsChars( bytes );
715         System.out.println( "Length = " + bytes.length );
716     }
717 
718     private void outputArrayAsInts( final byte[] bytes )
719     {
720         for( int i = 0; i < bytes.length; i++ )
721         {
722             System.out.print( bytes[ i ] + ", " );
723             if( 0 != i && i % 10 == 0 )
724             {
725                 System.out.println();
726             }
727         }
728         System.out.println();
729     }
730 
731     private void outputArrayAsChars( final byte[] bytes )
732     {
733         for( int i = 0; i < bytes.length; i++ )
734         {
735             System.out.print( ( (char)bytes[ i ] ) + ", " );
736             if( 0 != i && i % 10 == 0 )
737             {
738                 System.out.println();
739             }
740         }
741         System.out.println();
742     }
743 
744     private static final File generateDirectory()
745         throws IOException
746     {
747         final File baseDirectory = getBaseDirectory();
748         final File dir =
749             File.createTempFile( "mgtest", ".tmp", baseDirectory )
750             .getCanonicalFile();
751         dir.delete();
752         dir.mkdirs();
753         assertTrue( "dir.exists()", dir.exists() );
754         return dir;
755     }
756 
757     private static final File getBaseDirectory()
758     {
759         final String tempDir = System.getProperty( "java.io.tmpdir" );
760         final String baseDir = System.getProperty( "basedir", tempDir );
761 
762         final File base = new File( baseDir ).getAbsoluteFile();
763         final String pathname =
764             base + File.separator + "target" + File.separator + "test-data";
765         final File dir = new File( pathname );
766         dir.mkdirs();
767         return dir;
768     }
769 }