Clover coverage report - MetaClass - 1.1
Coverage timestamp: Tue Apr 27 2004 10:46:24 EST
file stats: LOC: 482   Methods: 20
NCLOC: 300   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
MetaClassIOBinary.java 100% 100% 100% 100%
coverage
 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.DataInputStream;
 11   
 import java.io.DataOutputStream;
 12   
 import java.io.File;
 13   
 import java.io.IOException;
 14   
 import java.io.InputStream;
 15   
 import java.io.OutputStream;
 16   
 import java.util.ArrayList;
 17   
 import java.util.Properties;
 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   
  * This is a utility class that writes out a Attributes object to a stream using
 26   
  * binary format outlined in documentation.
 27   
  *
 28   
  * @author Peter Donald
 29   
  * @author Doug Hagan
 30   
  * @version $Revision: 1.25 $ $Date: 2003/12/11 08:41:50 $
 31   
  */
 32   
 public class MetaClassIOBinary
 33   
     extends AbstractMetaClassIO
 34   
 {
 35   
     /** Constant with instance of MetaClassIO. */
 36   
     public static final MetaClassIOBinary IO = new MetaClassIOBinary();
 37   
 
 38   
     /** Extension of metadata files that are in binary format. */
 39   
     public static final String EXTENSION = "-meta.binary";
 40   
 
 41   
     /** The current version of Attributes object. */
 42   
     static final int VERSION = 2;
 43   
 
 44   
     /**
 45   
      * @see MetaClassIO#getResourceName(String)
 46   
      */
 47  32
     public String getResourceName( final String classname )
 48   
     {
 49  32
         return classname.replace( '.', File.separatorChar ) + EXTENSION;
 50   
     }
 51   
 
 52   
     /**
 53   
      * @see MetaClassIO#deserializeClass
 54   
      */
 55  36
     public ClassDescriptor deserializeClass( final InputStream input )
 56   
         throws IOException
 57   
     {
 58  36
         final DataInputStream data = new DataInputStream( input );
 59  36
         checkVersionHeader( data );
 60  30
         final String classname = data.readUTF();
 61  30
         final Attribute[] classAttributes = readAttributes( data );
 62   
 
 63  30
         final FieldDescriptor[] fields = readFields( data );
 64  30
         final MethodDescriptor[] methods = readMethods( data );
 65   
 
 66  30
         return
 67   
             new ClassDescriptor( classname,
 68   
                                  classAttributes,
 69   
                                  classAttributes,
 70   
                                  fields,
 71   
                                  methods );
 72   
     }
 73   
 
 74   
     /**
 75   
      * @see AbstractMetaClassIO#serializeClass(OutputStream, ClassDescriptor)
 76   
      */
 77  28
     public void serializeClass( final OutputStream output,
 78   
                                 final ClassDescriptor descriptor )
 79   
         throws IOException
 80   
     {
 81  28
         final DataOutputStream data = new DataOutputStream( output );
 82  28
         try
 83   
         {
 84  28
             data.writeInt( VERSION );
 85  28
             data.writeUTF( descriptor.getName() );
 86  28
             writeAttributes( data, descriptor.getAttributes() );
 87  28
             writeFields( data, descriptor.getFields() );
 88  28
             writeMethods( data, descriptor.getMethods() );
 89   
         }
 90   
         finally
 91   
         {
 92  28
             data.flush();
 93   
         }
 94   
     }
 95   
 
 96   
     /**
 97   
      * Write out a set of fields.
 98   
      *
 99   
      * @param data the output stream
 100   
      * @param fields the fields
 101   
      * @throws IOException if unable to write fields
 102   
      */
 103  32
     void writeFields( final DataOutputStream data,
 104   
                       final FieldDescriptor[] fields )
 105   
         throws IOException
 106   
     {
 107  32
         data.writeInt( fields.length );
 108  32
         for( int i = 0; i < fields.length; i++ )
 109   
         {
 110  4
             final FieldDescriptor field = fields[ i ];
 111  4
             writeField( data, field );
 112   
         }
 113   
     }
 114   
 
 115   
     /**
 116   
      * Write out a field.
 117   
      *
 118   
      * @param data the output stream
 119   
      * @param field the field
 120   
      * @throws IOException if unable to write field
 121   
      */
 122  4
     private void writeField( final DataOutputStream data,
 123   
                              final FieldDescriptor field )
 124   
         throws IOException
 125   
     {
 126  4
         data.writeUTF( field.getName() );
 127  4
         data.writeUTF( field.getType() );
 128  4
         writeAttributes( data, field.getAttributes() );
 129   
     }
 130   
 
 131   
     /**
 132   
      * Write out a set of methods.
 133   
      *
 134   
      * @param data the output stream
 135   
      * @param methods the methods
 136   
      * @throws IOException if unable to write methods
 137   
      */
 138  32
     void writeMethods( final DataOutputStream data,
 139   
                        final MethodDescriptor[] methods )
 140   
         throws IOException
 141   
     {
 142  32
         data.writeInt( methods.length );
 143  32
         for( int i = 0; i < methods.length; i++ )
 144   
         {
 145  4
             final MethodDescriptor method = methods[ i ];
 146  4
             writeMethod( data, method );
 147   
         }
 148   
     }
 149   
 
 150   
     /**
 151   
      * Write out a method.
 152   
      *
 153   
      * @param data the output stream
 154   
      * @param method the method
 155   
      * @throws IOException if unable to write method
 156   
      */
 157  4
     private void writeMethod( final DataOutputStream data,
 158   
                               final MethodDescriptor method )
 159   
         throws IOException
 160   
     {
 161  4
         data.writeUTF( method.getName() );
 162  4
         data.writeUTF( method.getReturnType() );
 163  4
         writeParameters( data, method.getParameters() );
 164  4
         writeAttributes( data, method.getAttributes() );
 165   
     }
 166   
 
 167   
     /**
 168   
      * Read in a set of methods.
 169   
      *
 170   
      * @param data the input
 171   
      * @return the methods
 172   
      * @throws IOException if unable to read methods
 173   
      */
 174  34
     MethodDescriptor[] readMethods( final DataInputStream data )
 175   
         throws IOException
 176   
     {
 177  34
         final int count = data.readInt();
 178  34
         if( 0 == count )
 179   
         {
 180  30
             return MethodDescriptor.EMPTY_SET;
 181   
         }
 182  4
         final ArrayList methodSet = new ArrayList();
 183  4
         for( int i = 0; i < count; i++ )
 184   
         {
 185  4
             methodSet.add( readMethod( data ) );
 186   
         }
 187   
 
 188  4
         return (MethodDescriptor[])methodSet.
 189   
             toArray( new MethodDescriptor[ methodSet.size() ] );
 190   
     }
 191   
 
 192   
     /**
 193   
      * Read in a method.
 194   
      *
 195   
      * @param data the input
 196   
      * @return the method
 197   
      * @throws IOException if unable to read method
 198   
      */
 199  4
     private MethodDescriptor readMethod( final DataInputStream data )
 200   
         throws IOException
 201   
     {
 202  4
         final String name = data.readUTF();
 203  4
         final String type = data.readUTF();
 204  4
         final ParameterDescriptor[] parameters = readParameters( data );
 205  4
         final Attribute[] attributes = readAttributes( data );
 206  4
         return
 207   
             new MethodDescriptor( name,
 208   
                                   type,
 209   
                                   parameters,
 210   
                                   attributes,
 211   
                                   attributes );
 212   
     }
 213   
 
 214   
     /**
 215   
      * Read in a set of fields.
 216   
      *
 217   
      * @param data the input
 218   
      * @return the fields
 219   
      * @throws IOException if unable to read fields
 220   
      */
 221  34
     FieldDescriptor[] readFields( final DataInputStream data )
 222   
         throws IOException
 223   
     {
 224  34
         final int count = data.readInt();
 225  34
         if( 0 == count )
 226   
         {
 227  30
             return FieldDescriptor.EMPTY_SET;
 228   
         }
 229   
 
 230  4
         final ArrayList fieldSet = new ArrayList();
 231  4
         for( int i = 0; i < count; i++ )
 232   
         {
 233  4
             fieldSet.add( readField( data ) );
 234   
         }
 235  4
         return (FieldDescriptor[])fieldSet.
 236   
             toArray( new FieldDescriptor[ fieldSet.size() ] );
 237   
     }
 238   
 
 239   
     /**
 240   
      * Read in a field.
 241   
      *
 242   
      * @param data the input
 243   
      * @return the field
 244   
      * @throws IOException if unable to read field
 245   
      */
 246  4
     private FieldDescriptor readField( final DataInputStream data )
 247   
         throws IOException
 248   
     {
 249  4
         final String name = data.readUTF();
 250  4
         final String type = data.readUTF();
 251  4
         final Attribute[] attributes = readAttributes( data );
 252  4
         return new FieldDescriptor( name, type, attributes, attributes );
 253   
     }
 254   
 
 255   
     /**
 256   
      * Read in a set of method parameters.
 257   
      *
 258   
      * @param data the input
 259   
      * @return the method parameters
 260   
      * @throws IOException if unable to read parameters
 261   
      */
 262  8
     ParameterDescriptor[] readParameters( final DataInputStream data )
 263   
         throws IOException
 264   
     {
 265  8
         final int count = data.readInt();
 266  8
         if( 0 == count )
 267   
         {
 268  6
             return ParameterDescriptor.EMPTY_SET;
 269   
         }
 270   
 
 271  2
         final ArrayList parameters = new ArrayList();
 272  2
         for( int i = 0; i < count; i++ )
 273   
         {
 274  2
             parameters.add( readParameter( data ) );
 275   
         }
 276  2
         return (ParameterDescriptor[])parameters.
 277   
             toArray( new ParameterDescriptor[ parameters.size() ] );
 278   
     }
 279   
 
 280   
     /**
 281   
      * Read in a method parameter.
 282   
      *
 283   
      * @param data the input
 284   
      * @return the method parameter
 285   
      * @throws IOException if unable to read parameter
 286   
      */
 287  2
     private ParameterDescriptor readParameter( final DataInputStream data )
 288   
         throws IOException
 289   
     {
 290  2
         final String name = data.readUTF();
 291  2
         final String type = data.readUTF();
 292  2
         return new ParameterDescriptor( name, type );
 293   
     }
 294   
 
 295   
     /**
 296   
      * Write out a set of method parameters.
 297   
      *
 298   
      * @param data the output stream
 299   
      * @param parameters the method parameters
 300   
      * @throws IOException if unable to write parameters
 301   
      */
 302  8
     void writeParameters( final DataOutputStream data,
 303   
                           final ParameterDescriptor[] parameters )
 304   
         throws IOException
 305   
     {
 306  8
         data.writeInt( parameters.length );
 307  8
         for( int i = 0; i < parameters.length; i++ )
 308   
         {
 309  2
             final ParameterDescriptor parameter = parameters[ i ];
 310  2
             writeParameter( data, parameter );
 311   
         }
 312   
     }
 313   
 
 314   
     /**
 315   
      * Write out a method parameter.
 316   
      *
 317   
      * @param data the output stream
 318   
      * @param parameter the method parameter
 319   
      * @throws IOException if unable to write parameter
 320   
      */
 321  2
     private void writeParameter( final DataOutputStream data,
 322   
                                  final ParameterDescriptor parameter )
 323   
         throws IOException
 324   
     {
 325  2
         data.writeUTF( parameter.getName() );
 326  2
         data.writeUTF( parameter.getType() );
 327   
     }
 328   
 
 329   
     /**
 330   
      * Read in a set of attributes.
 331   
      *
 332   
      * @param data the input stream
 333   
      * @return the attributes
 334   
      * @throws IOException if unable to read attributes
 335   
      */
 336  48
     Attribute[] readAttributes( final DataInputStream data )
 337   
         throws IOException
 338   
     {
 339  48
         final int count = data.readInt();
 340  48
         if( 0 == count )
 341   
         {
 342  20
             return Attribute.EMPTY_SET;
 343   
         }
 344  28
         final ArrayList attributeSet = new ArrayList();
 345  28
         for( int i = 0; i < count; i++ )
 346   
         {
 347  30
             final String name = data.readUTF();
 348  30
             final String value = data.readUTF();
 349  30
             final Properties properties = readAttributeParameters( data );
 350   
 
 351  30
             final boolean valuePresent = null != value && value.length() > 0;
 352  30
             if( valuePresent &&
 353   
                 properties.size() > 0 )
 354   
             {
 355  2
                 final String message =
 356   
                     "Cannot read attributes containing both " +
 357   
                     "text and parameters.";
 358  2
                 throw new IOException( message );
 359   
             }
 360   
 
 361  28
             final Attribute attribute;
 362  28
             if( valuePresent )
 363   
             {
 364  4
                 attribute = new Attribute( name, value );
 365   
             }
 366   
             else
 367   
             {
 368  24
                 attribute = new Attribute( name, properties );
 369   
             }
 370  28
             attributeSet.add( attribute );
 371   
         }
 372   
 
 373  26
         return (Attribute[])attributeSet.toArray(
 374   
             new Attribute[ attributeSet.size() ] );
 375   
     }
 376   
 
 377   
     /**
 378   
      * Read in a set of attribute parameters.
 379   
      *
 380   
      * @param data the input
 381   
      * @return the parameters
 382   
      * @throws IOException if unable to read attribute parameters
 383   
      */
 384  30
     Properties readAttributeParameters( final DataInputStream data )
 385   
         throws IOException
 386   
     {
 387  30
         final Properties parameters = new Properties();
 388   
 
 389  30
         final int count = data.readInt();
 390  30
         for( int i = 0; i < count; i++ )
 391   
         {
 392  6
             final String name = data.readUTF();
 393  6
             final String value = data.readUTF();
 394  6
             parameters.setProperty( name, value );
 395   
         }
 396   
 
 397  30
         return parameters;
 398   
     }
 399   
 
 400   
     /**
 401   
      * Write out the specified attributes.
 402   
      *
 403   
      * @param data the output
 404   
      * @param attributes the attributes
 405   
      * @throws IOException if unable to write attributes
 406   
      */
 407  44
     void writeAttributes( final DataOutputStream data,
 408   
                           final Attribute[] attributes )
 409   
         throws IOException
 410   
     {
 411  44
         data.writeInt( attributes.length );
 412  44
         for( int i = 0; i < attributes.length; i++ )
 413   
         {
 414  28
             final Attribute attribute = attributes[ i ];
 415  28
             data.writeUTF( attribute.getName() );
 416   
 
 417  28
             final String value = attribute.getValue();
 418  28
             if( null != value )
 419   
             {
 420  4
                 data.writeUTF( value );
 421  4
                 writeAttributeParameters( data, null );
 422   
             }
 423   
             else
 424   
             {
 425  24
                 data.writeUTF( "" );
 426  24
                 writeAttributeParameters( data, attribute );
 427   
             }
 428   
         }
 429   
     }
 430   
 
 431   
     /**
 432   
      * Write out the parameters of an attribute.
 433   
      *
 434   
      * @param data the output
 435   
      * @param attribute the attribute
 436   
      * @throws IOException if unable to write attribute parameters
 437   
      */
 438  28
     void writeAttributeParameters( final DataOutputStream data,
 439   
                                    final Attribute attribute )
 440   
         throws IOException
 441   
     {
 442  28
         if( null == attribute )
 443   
         {
 444  4
             data.writeInt( 0 );
 445   
         }
 446   
         else
 447   
         {
 448  24
             final String[] names = attribute.getParameterNames();
 449  24
             data.writeInt( names.length );
 450  24
             for( int i = 0; i < names.length; i++ )
 451   
             {
 452  4
                 final String name = names[ i ];
 453  4
                 final String value = attribute.getParameter( name );
 454  4
                 data.writeUTF( name );
 455  4
                 data.writeUTF( value );
 456   
             }
 457   
         }
 458   
     }
 459   
 
 460   
     /**
 461   
      * Read version header of descriptor to make sure it is something we can
 462   
      * handle and if not throw an exception.
 463   
      *
 464   
      * @param data the input stream
 465   
      * @throws IOException if unable to handle version
 466   
      */
 467  36
     private void checkVersionHeader( final DataInputStream data )
 468   
         throws IOException
 469   
     {
 470  36
         final int version = data.readInt();
 471  34
         if( VERSION != version )
 472   
         {
 473  4
             final String message =
 474   
                 "Version mismatch." +
 475   
                 " Expected: " +
 476   
                 VERSION +
 477   
                 " Actual: " + version;
 478  4
             throw new IOException( message );
 479   
         }
 480   
     }
 481   
 }
 482