|
|||||||||||||||||||
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% |
|
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 |
|
|