KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > emma > data > DataFactory


1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: DataFactory.java,v 1.1.1.1.2.3 2004/07/16 23:32:29 vlad_r Exp $
8  */

9 package com.vladium.emma.data;
10
11 import java.io.BufferedInputStream JavaDoc;
12 import java.io.BufferedOutputStream JavaDoc;
13 import java.io.DataInput JavaDoc;
14 import java.io.DataInputStream JavaDoc;
15 import java.io.DataOutput JavaDoc;
16 import java.io.DataOutputStream JavaDoc;
17 import java.io.File JavaDoc;
18 import java.io.FileDescriptor JavaDoc;
19 import java.io.FileInputStream JavaDoc;
20 import java.io.FileOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.ObjectInputStream JavaDoc;
23 import java.io.ObjectOutputStream JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.io.RandomAccessFile JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.net.URLConnection JavaDoc;
28
29 import com.vladium.logging.Logger;
30 import com.vladium.util.asserts.$assert;
31 import com.vladium.emma.IAppConstants;
32
33 // ----------------------------------------------------------------------------
34
/**
35  * @author Vlad Roubtsov, (C) 2003
36  */

37 public
38 abstract class DataFactory
39 {
40     // public: ................................................................
41

42     // TODO: file compaction
43
// TODO: file locking
44

45     // TODO: what's the best place for these?
46

47     public static final byte TYPE_METADATA = 0x0; // must start with 0
48
public static final byte TYPE_COVERAGEDATA = 0x1; // must be consistent with mergeload()
49

50     
51     public static IMergeable [] load (final File JavaDoc file)
52         throws IOException JavaDoc
53     {
54         if (file == null) throw new IllegalArgumentException JavaDoc ("null input: file");
55         
56         return mergeload (file);
57     }
58     
59     public static void persist (final IMetaData data, final File JavaDoc file, final boolean merge)
60         throws IOException JavaDoc
61     {
62         if (data == null) throw new IllegalArgumentException JavaDoc ("null input: data");
63         if (file == null) throw new IllegalArgumentException JavaDoc ("null input: file");
64         
65         if (! merge && file.exists ())
66         {
67             if (! file.delete ())
68                 throw new IOException JavaDoc ("could not delete file [" + file.getAbsolutePath () + "]");
69         }
70         
71         persist (data, TYPE_METADATA, file);
72     }
73     
74     public static void persist (final ICoverageData data, final File JavaDoc file, final boolean merge)
75         throws IOException JavaDoc
76     {
77         if (data == null) throw new IllegalArgumentException JavaDoc ("null input: data");
78         if (file == null) throw new IllegalArgumentException JavaDoc ("null input: file");
79         
80         if (! merge && file.exists ())
81         {
82             if (! file.delete ())
83                 throw new IOException JavaDoc ("could not delete file [" + file.getAbsolutePath () + "]");
84         }
85         
86         persist (data, TYPE_COVERAGEDATA, file);
87     }
88     
89     public static void persist (final ISessionData data, final File JavaDoc file, final boolean merge)
90         throws IOException JavaDoc
91     {
92         if (data == null) throw new IllegalArgumentException JavaDoc ("null input: data");
93         if (file == null) throw new IllegalArgumentException JavaDoc ("null input: file");
94         
95         if (! merge && file.exists ())
96         {
97             if (! file.delete ())
98                 throw new IOException JavaDoc ("could not delete file [" + file.getAbsolutePath () + "]");
99         }
100         
101         persist (data.getMetaData (), TYPE_METADATA, file);
102         persist (data.getCoverageData (), TYPE_COVERAGEDATA, file);
103     }
104
105     
106     public static IMetaData newMetaData (final CoverageOptions options)
107     {
108         return new MetaData (options);
109     }
110     
111     public static ICoverageData newCoverageData ()
112     {
113         return new CoverageData ();
114     }
115
116     public static IMetaData readMetaData (final URL JavaDoc url)
117         throws IOException JavaDoc, ClassNotFoundException JavaDoc
118     {
119         ObjectInputStream JavaDoc oin = null;
120         
121         try
122         {
123             oin = new ObjectInputStream JavaDoc (new BufferedInputStream JavaDoc (url.openStream (), 32 * 1024));
124             
125             return (IMetaData) oin.readObject ();
126         }
127         finally
128         {
129             if (oin != null) try { oin.close (); } catch (Exception JavaDoc ignore) {}
130         }
131     }
132     
133     public static void writeMetaData (final IMetaData data, final OutputStream JavaDoc out)
134         throws IOException JavaDoc
135     {
136         ObjectOutputStream JavaDoc oout = new ObjectOutputStream JavaDoc (out);
137         oout.writeObject (data);
138     }
139     
140     public static void writeMetaData (final IMetaData data, final URL JavaDoc url)
141         throws IOException JavaDoc
142     {
143         final URLConnection JavaDoc connection = url.openConnection ();
144         connection.setDoOutput (true);
145         
146         OutputStream JavaDoc out = null;
147         try
148         {
149             out = connection.getOutputStream ();
150             
151             writeMetaData (data, out);
152             out.flush ();
153         }
154         finally
155         {
156             if (out != null) try { out.close (); } catch (Exception JavaDoc ignore) {}
157         }
158     }
159     
160     public static ICoverageData readCoverageData (final URL JavaDoc url)
161         throws IOException JavaDoc, ClassNotFoundException JavaDoc
162     {
163         ObjectInputStream JavaDoc oin = null;
164         
165         try
166         {
167             oin = new ObjectInputStream JavaDoc (new BufferedInputStream JavaDoc (url.openStream (), 32 * 1024));
168             
169             return (ICoverageData) oin.readObject ();
170         }
171         finally
172         {
173             if (oin != null) try { oin.close (); } catch (Exception JavaDoc ignore) {}
174         }
175     }
176     
177     public static void writeCoverageData (final ICoverageData data, final OutputStream JavaDoc out)
178         throws IOException JavaDoc
179     {
180         // TODO: prevent concurrent modification problems here
181

182         ObjectOutputStream JavaDoc oout = new ObjectOutputStream JavaDoc (out);
183         oout.writeObject (data);
184     }
185     
186     public static int [] readIntArray (final DataInput JavaDoc in)
187         throws IOException JavaDoc
188     {
189         final int length = in.readInt ();
190         if (length == NULL_ARRAY_LENGTH)
191             return null;
192         else
193         {
194             final int [] result = new int [length];
195             
196             // read array in reverse order:
197
for (int i = length; -- i >= 0; )
198             {
199                 result [i] = in.readInt ();
200             }
201             
202             return result;
203         }
204     }
205     
206     public static boolean [] readBooleanArray (final DataInput JavaDoc in)
207         throws IOException JavaDoc
208     {
209         final int length = in.readInt ();
210         if (length == NULL_ARRAY_LENGTH)
211             return null;
212         else
213         {
214             final boolean [] result = new boolean [length];
215             
216             // read array in reverse order:
217
for (int i = length; -- i >= 0; )
218             {
219                 result [i] = in.readBoolean ();
220             }
221             
222             return result;
223         }
224     }
225     
226     public static void writeIntArray (final int [] array, final DataOutput JavaDoc out)
227         throws IOException JavaDoc
228     {
229         if (array == null)
230             out.writeInt (NULL_ARRAY_LENGTH);
231         else
232         {
233             final int length = array.length;
234             out.writeInt (length);
235             
236             // write array in reverse order:
237
for (int i = length; -- i >= 0; )
238             {
239                 out.writeInt (array [i]);
240             }
241         }
242     }
243     
244     public static void writeBooleanArray (final boolean [] array, final DataOutput JavaDoc out)
245         throws IOException JavaDoc
246     {
247         if (array == null)
248             out.writeInt (NULL_ARRAY_LENGTH);
249         else
250         {
251             final int length = array.length;
252             out.writeInt (length);
253             
254             // write array in reverse order:
255
for (int i = length; -- i >= 0; )
256             {
257                 out.writeBoolean (array [i]);
258             }
259         }
260     }
261     
262     // protected: .............................................................
263

264     // package: ...............................................................
265

266     // private: ...............................................................
267

268
269     private static final class UCFileInputStream extends FileInputStream JavaDoc
270     {
271         public void close ()
272         {
273         }
274         
275         UCFileInputStream (final FileDescriptor JavaDoc fd)
276         {
277             super (fd);
278             
279             if ($assert.ENABLED) $assert.ASSERT (fd.valid (), "UCFileInputStream.<init>: FD invalid");
280         }
281         
282     } // end of nested class
283

284     private static final class UCFileOutputStream extends FileOutputStream JavaDoc
285     {
286         public void close ()
287         {
288         }
289         
290         UCFileOutputStream (final FileDescriptor JavaDoc fd)
291         {
292             super (fd);
293             
294             if ($assert.ENABLED) $assert.ASSERT (fd.valid (), "UCFileOutputStream.<init>: FD invalid");
295         }
296         
297     } // end of nested class
298

299     
300     private static final class RandomAccessFileInputStream extends BufferedInputStream JavaDoc
301     {
302         public final int read () throws IOException JavaDoc
303         {
304             final int rc = super.read ();
305             if (rc >= 0) ++ m_count;
306             
307             return rc;
308         }
309
310         public final int read (final byte [] b, final int off, final int len)
311             throws IOException JavaDoc
312         {
313             final int rc = super.read (b, off, len);
314             if (rc >= 0) m_count += rc;
315             
316             return rc;
317         }
318
319         public final int read (final byte [] b) throws IOException JavaDoc
320         {
321             final int rc = super.read (b);
322             if (rc >= 0) m_count += rc;
323             
324             return rc;
325         }
326         
327         public void close ()
328         {
329         }
330
331
332         RandomAccessFileInputStream (final RandomAccessFile JavaDoc raf, final int bufSize)
333             throws IOException JavaDoc
334         {
335             super (new UCFileInputStream (raf.getFD ()), bufSize);
336         }
337         
338         final long getCount ()
339         {
340             return m_count;
341         }
342         
343         private long m_count;
344
345     } // end of nested class
346

347     private static final class RandomAccessFileOutputStream extends BufferedOutputStream JavaDoc
348     {
349         public final void write (final byte [] b, final int off, final int len) throws IOException JavaDoc
350         {
351             super.write (b, off, len);
352             m_count += len;
353         }
354
355         public final void write (final byte [] b) throws IOException JavaDoc
356         {
357             super.write (b);
358             m_count += b.length;
359         }
360
361         public final void write (final int b) throws IOException JavaDoc
362         {
363             super.write (b);
364             ++ m_count;
365         }
366         
367         public void close ()
368         {
369         }
370         
371         
372         RandomAccessFileOutputStream (final RandomAccessFile JavaDoc raf, final int bufSize)
373             throws IOException JavaDoc
374         {
375             super (new UCFileOutputStream (raf.getFD ()), bufSize);
376         }
377         
378         final long getCount ()
379         {
380             return m_count;
381         }
382         
383         private long m_count;
384
385     } // end of nested class
386

387     
388     private DataFactory () {} // prevent subclassing
389

390     /*
391      * input checked by the caller
392      */

393     private static IMergeable [] mergeload (final File JavaDoc file)
394         throws IOException JavaDoc
395     {
396         final Logger log = Logger.getLogger ();
397         final boolean trace1 = log.atTRACE1 ();
398         final boolean trace2 = log.atTRACE2 ();
399         final String JavaDoc method = "mergeload";
400         
401         long start = 0, end;
402         
403         if (trace1) start = System.currentTimeMillis ();
404         
405         final IMergeable [] result = new IMergeable [2];
406         
407         if (! file.exists ())
408         {
409             throw new IOException JavaDoc ("input file does not exist: [" + file.getAbsolutePath () + "]");
410         }
411         else
412         {
413             RandomAccessFile JavaDoc raf = null;
414             try
415             {
416                 raf = new RandomAccessFile JavaDoc (file, "r");
417                 
418                 // 'file' is a valid existing file, but it could still be of 0 length or otherwise corrupt:
419
final long length = raf.length ();
420                 if (trace1) log.trace1 (method, "[" + file + "]: file length = " + length);
421                 
422                 if (length < FILE_HEADER_LENGTH)
423                 {
424                     throw new IOException JavaDoc ("file [" + file.getAbsolutePath () + "] is corrupt or was not created by " + IAppConstants.APP_NAME);
425                 }
426                 else
427                 {
428                     // TODO: data version checks parallel to persist()
429

430                     if (length > FILE_HEADER_LENGTH) // return {null, null} in case of equality
431
{
432                         raf.seek (FILE_HEADER_LENGTH);
433                                 
434                         // [assertion: file length > FILE_HEADER_LENGTH]
435

436                         // read entries until the first corrupt entry or the end of the file:
437

438                         long position = FILE_HEADER_LENGTH;
439                         long entryLength;
440                         
441                         long entrystart = 0;
442                         
443                         while (true)
444                         {
445                             if (trace2) log.trace2 (method, "[" + file + "]: position " + raf.getFilePointer ());
446                             if (position >= length) break;
447                             
448                             entryLength = raf.readLong ();
449                             
450                             if ((entryLength <= 0) || (position + entryLength + ENTRY_HEADER_LENGTH > length))
451                                 break;
452                             else
453                             {
454                                 final byte type = raf.readByte ();
455                                 if ((type < 0) || (type >= result.length))
456                                     break;
457                                     
458                                 if (trace2) log.trace2 (method, "[" + file + "]: found valid entry of size " + entryLength + " and type " + type);
459                                 {
460                                     if (trace2) entrystart = System.currentTimeMillis ();
461                                     final IMergeable data = readEntry (raf, type, entryLength);
462                                     if (trace2) log.trace2 (method, "entry read in " + (System.currentTimeMillis () - entrystart) + " ms");
463                                     
464                                     final IMergeable current = result [type];
465                                     
466                                     if (current == null)
467                                         result [type] = data;
468                                     else
469                                         result [type] = current.merge (data); // note: later entries overrides earlier entries
470
}
471                                 
472                                 position += entryLength + ENTRY_HEADER_LENGTH;
473                                 
474                                 if ($assert.ENABLED) $assert.ASSERT (raf.getFD ().valid (), "FD invalid");
475                                 raf.seek (position);
476                             }
477                         }
478                     }
479                 }
480             }
481             finally
482             {
483                 if (raf != null) try { raf.close (); } catch (Throwable JavaDoc ignore) {}
484                 raf = null;
485             }
486         }
487         
488         if (trace1)
489         {
490             end = System.currentTimeMillis ();
491             
492             log.trace1 (method, "[" + file + "]: file processed in " + (end - start) + " ms");
493         }
494         
495         return result;
496     }
497
498
499     /*
500      * input checked by the caller
501      */

502     private static void persist (final IMergeable data, final byte type, final File JavaDoc file)
503         throws IOException JavaDoc
504     {
505         final Logger log = Logger.getLogger ();
506         final boolean trace1 = log.atTRACE1 ();
507         final boolean trace2 = log.atTRACE2 ();
508         final String JavaDoc method = "persist";
509         
510         long start = 0, end;
511         
512         if (trace1) start = System.currentTimeMillis ();
513         
514         // TODO: 1.4 adds some interesting RAF open mode options as well
515
// TODO: will this benefit from extra buffering?
516

517         // TODO: data version checks
518

519         RandomAccessFile JavaDoc raf = null;
520         try
521         {
522             boolean overwrite = false;
523             boolean truncate = false;
524                         
525             if (file.exists ())
526             {
527                 // 'file' exists:
528

529                 if (! file.isFile ()) throw new IOException JavaDoc ("can persist in normal files only: " + file.getAbsolutePath ());
530                 
531                 raf = new RandomAccessFile JavaDoc (file, "rw");
532                 
533                 // 'file' is a valid existing file, but it could still be of 0 length or otherwise corrupt:
534
final long length = raf.length ();
535                 if (trace1) log.trace1 (method, "[" + file + "]: existing file length = " + length);
536                 
537                 
538                 if (length < 4)
539                 {
540                     overwrite = true;
541                     truncate = (length > 0);
542                 }
543                 else
544                 {
545                     // [assertion: file length >= 4]
546

547                     // check header info before reading further:
548
final int magic = raf.readInt ();
549                     if (magic != MAGIC)
550                         throw new IOException JavaDoc ("cannot overwrite [" + file.getAbsolutePath () + "]: not created by " + IAppConstants.APP_NAME);
551                     
552                     if (length < FILE_HEADER_LENGTH)
553                     {
554                         // it's our file, but the header is corrupt: overwrite
555
overwrite = true;
556                         truncate = true;
557                     }
558                     else
559                     {
560                         // [assertion: file length >= FILE_HEADER_LENGTH]
561

562 // if (! append)
563
// {
564
// // overwrite any existing data:
565
//
566
// raf.seek (FILE_HEADER_LENGTH);
567
// writeEntry (raf, FILE_HEADER_LENGTH, data, type);
568
// }
569
// else
570
{
571                             // check data format version info:
572
final long dataVersion = raf.readLong ();
573                             
574                             if (dataVersion != IAppConstants.DATA_FORMAT_VERSION)
575                             {
576                                 // read app version info for the error message:
577

578                                 int major = 0, minor = 0, build = 0;
579                                 boolean gotAppVersion = false;
580                                 try
581                                 {
582                                     major = raf.readInt ();
583                                     minor = raf.readInt ();
584                                     build = raf.readInt ();
585                                     
586                                     gotAppVersion = true;
587                                 }
588                                 catch (Throwable JavaDoc ignore) {}
589                                 
590                                 // TODO: error code here?
591
if (gotAppVersion)
592                                 {
593                                     throw new IOException JavaDoc ("cannot merge new data into [" + file.getAbsolutePath () + "]: created by another " + IAppConstants.APP_NAME + " version [" + makeAppVersion (major, minor, build) + "]");
594                                 }
595                                 else
596                                 {
597                                     throw new IOException JavaDoc ("cannot merge new data into [" + file.getAbsolutePath () + "]: created by another " + IAppConstants.APP_NAME + " version");
598                                 }
599                             }
600                             else
601                             {
602                                 // [assertion: file header is valid and data format version is consistent]
603

604                                 raf.seek (FILE_HEADER_LENGTH);
605                                 
606                                 if (length == FILE_HEADER_LENGTH)
607                                 {
608                                     // no previous data entries: append 'data'
609

610                                     writeEntry (log, raf, FILE_HEADER_LENGTH, data, type);
611                                 }
612                                 else
613                                 {
614                                     // [assertion: file length > FILE_HEADER_LENGTH]
615

616                                     // write 'data' starting with the first corrupt entry or the end of the file:
617

618                                     long position = FILE_HEADER_LENGTH;
619                                     long entryLength;
620                                     
621                                     while (true)
622                                     {
623                                         if (trace2) log.trace2 (method, "[" + file + "]: position " + raf.getFilePointer ());
624                                         if (position >= length) break;
625                                         
626                                         entryLength = raf.readLong ();
627                                         
628                                         if ((entryLength <= 0) || (position + entryLength + ENTRY_HEADER_LENGTH > length))
629                                             break;
630                                         else
631                                         {
632                                             if (trace2) log.trace2 (method, "[" + file + "]: found valid entry of size " + entryLength);
633                                             
634                                             position += entryLength + ENTRY_HEADER_LENGTH;
635                                             raf.seek (position);
636                                         }
637                                     }
638                                     
639                                     if (trace2) log.trace2 (method, "[" + file + "]: adding entry at position " + position);
640                                     writeEntry (log, raf, position, data, type);
641                                 }
642                             }
643                         }
644                     }
645                 }
646             }
647             else
648             {
649                 // 'file' does not exist:
650

651                 if (trace1) log.trace1 (method, "[" + file + "]: creating a new file");
652                 
653                 final File JavaDoc parent = file.getParentFile ();
654                 if (parent != null) parent.mkdirs ();
655                 
656                 raf = new RandomAccessFile JavaDoc (file, "rw");
657                 
658                 overwrite = true;
659             }
660             
661             
662             if (overwrite)
663             {
664                 // persist starting from 0 offset:
665

666                 if ($assert.ENABLED) $assert.ASSERT (raf != null, "raf = null");
667                 
668                 if (truncate) raf.seek (0);
669                 writeFileHeader (raf);
670                 if ($assert.ENABLED) $assert.ASSERT (raf.getFilePointer () == FILE_HEADER_LENGTH, "invalid header length: " + raf.getFilePointer ());
671                 
672                 writeEntry (log, raf, FILE_HEADER_LENGTH, data, type);
673             }
674         }
675         finally
676         {
677             if (raf != null) try { raf.close (); } catch (Throwable JavaDoc ignore) {}
678             raf = null;
679         }
680         
681         if (trace1)
682         {
683             end = System.currentTimeMillis ();
684             
685             log.trace1 (method, "[" + file + "]: file processed in " + (end - start) + " ms");
686         }
687     }
688     
689     private static void writeFileHeader (final DataOutput JavaDoc out)
690         throws IOException JavaDoc
691     {
692         out.writeInt (MAGIC);
693         
694         out.writeLong (IAppConstants.DATA_FORMAT_VERSION);
695         
696         out.writeInt (IAppConstants.APP_MAJOR_VERSION);
697         out.writeInt (IAppConstants.APP_MINOR_VERSION);
698         out.writeInt (IAppConstants.APP_BUILD_ID);
699     }
700     
701     private static void writeEntryHeader (final DataOutput JavaDoc out, final byte type)
702         throws IOException JavaDoc
703     {
704         out.writeLong (UNKNOWN); // length placeholder
705
out.writeByte (type);
706     }
707     
708     private static void writeEntry (final Logger log, final RandomAccessFile JavaDoc raf, final long marker, final IMergeable data, final byte type)
709         throws IOException JavaDoc
710     {
711         // [unfinished] entry header:
712
writeEntryHeader (raf, type);
713         
714         // serialize 'data' starting with the current raf position:
715
RandomAccessFileOutputStream rafout = new RandomAccessFileOutputStream (raf, IO_BUF_SIZE); // note: no new file descriptors created here
716
{
717 // ObjectOutputStream oout = new ObjectOutputStream (rafout);
718
//
719
// oout.writeObject (data);
720
// oout.flush ();
721
// oout = null;
722

723             DataOutputStream JavaDoc dout = new DataOutputStream JavaDoc (rafout);
724             switch (type)
725             {
726                 case TYPE_METADATA: MetaData.writeExternal ((MetaData) data, dout);
727                     break;
728                     
729                 default /* TYPE_COVERAGEDATA */: CoverageData.writeExternal ((CoverageData) data, dout);
730                     break;
731                     
732             } // end of switch
733
dout.flush ();
734             dout = null;
735             
736             // truncate:
737
raf.setLength (raf.getFilePointer ());
738         }
739
740         // transact this entry [finish the header]:
741
raf.seek (marker);
742         raf.writeLong (rafout.getCount ());
743         if (DO_FSYNC) raf.getFD ().sync ();
744         
745         if (log.atTRACE2 ()) log.trace2 ("writeEntry", "entry [" + data.getClass ().getName () + "] length: " + rafout.getCount ());
746     }
747     
748     private static IMergeable readEntry (final RandomAccessFile JavaDoc raf, final byte type, final long entryLength)
749         throws IOException JavaDoc
750     {
751         final Object JavaDoc data;
752         
753         RandomAccessFileInputStream rafin = new RandomAccessFileInputStream (raf, IO_BUF_SIZE); // note: no new file descriptors created here
754
{
755 // ObjectInputStream oin = new ObjectInputStream (rafin);
756
//
757
// try
758
// {
759
// data = oin.readObject ();
760
// }
761
// catch (ClassNotFoundException cnfe)
762
// {
763
// // TODO: EMMA exception here
764
// throw new IOException ("could not read data entry: " + cnfe.toString ());
765
// }
766

767             DataInputStream JavaDoc din = new DataInputStream JavaDoc (rafin);
768             switch (type)
769             {
770                 case TYPE_METADATA: data = MetaData.readExternal (din);
771                     break;
772                     
773                 default /* TYPE_COVERAGEDATA */: data = CoverageData.readExternal (din);
774                     break;
775                     
776             } // end of switch
777
}
778         
779         if ($assert.ENABLED) $assert.ASSERT (rafin.getCount () == entryLength, "entry length mismatch: " + rafin.getCount () + " != " + entryLength);
780         
781         return (IMergeable) data;
782     }
783     
784     
785     /*
786      * This is cloned from EMMAProperties by design, to eliminate a CONSTANT_Class_info
787      * dependency between this and EMMAProperties classes.
788      */

789     private static String JavaDoc makeAppVersion (final int major, final int minor, final int build)
790     {
791         final StringBuffer JavaDoc buf = new StringBuffer JavaDoc ();
792         
793         buf.append (major);
794         buf.append ('.');
795         buf.append (minor);
796         buf.append ('.');
797         buf.append (build);
798         
799         return buf.toString ();
800     }
801     
802
803     private static final int NULL_ARRAY_LENGTH = -1;
804     
805     private static final int MAGIC = 0x454D4D41; // "EMMA"
806
private static final long UNKNOWN = 0L;
807     private static final int FILE_HEADER_LENGTH = 4 + 8 + 3 * 4; // IMPORTANT: update on writeFileHeader() changes
808
private static final int ENTRY_HEADER_LENGTH = 8 + 1; // IMPORTANT: update on writeEntryHeader() changes
809
private static final boolean DO_FSYNC = true;
810     private static final int IO_BUF_SIZE = 32 * 1024;
811     
812 } // end of class
813
// ----------------------------------------------------------------------------
814
Popular Tags