KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > commons > cbutil > CBCache


1 package com.ca.commons.cbutil;
2
3 import javax.naming.NamingException JavaDoc;
4 import javax.naming.directory.Attribute JavaDoc;
5 import javax.naming.directory.Attributes JavaDoc;
6 import java.io.*;
7 import java.util.Arrays JavaDoc;
8 import java.util.Comparator JavaDoc;
9 import java.util.logging.Level JavaDoc;
10 import java.util.logging.Logger JavaDoc;
11
12
13 /**
14  * This class creates a cache directory called 'temp' where temporary files are stored.
15  * Currently it works for audio, jpegPhoto and odDocumentDOC attributes. The audio
16  * are stored in a sub dir called 'audio'. It also contains methods
17  * for decreasing the cache size, cleaning (or emptying the cache and sorting the
18  * temporary files according to their last modified date.
19  *
20  * @author Trudi.
21  */

22
23 public class CBCache
24 {
25     private static int counter = 0; //TE: a counter that is used to but a unique number on the temp files.
26
private static int CACHEMAX = 100; //TE: the maximum size the cache should ever reach before decreasing its size.
27
private static int CACHEMIN = 50; //TE: the size the cache gets minimized to when decreaseing its size.
28
private static File fileDir = null; //TE: the directory that the temp files are stored.
29
private static File audioFileDir = null; //TE: the directory that the audio temp files are stored.
30
private static String JavaDoc allFiles[]; //TE: an array to store the files within the temp directory.
31
private static String JavaDoc allAudioFiles[]; //TE: an array to store the files within the audio temp directory.
32
private static String JavaDoc extension = ".jpg"; //TE: the extension of the temporary file.
33
private static String JavaDoc dirPath = "temp";
34
35     private static Logger JavaDoc log = Logger.getLogger(CBCache.class.getName());
36
37
38     /**
39      * Creates a cache directory named 'temp' and adds temporary files to it currently naming them (for example)
40      * with the hash of their 'DN + a unique number + .jpg'.
41      *
42      * @param currentDN the dn of the entry being modified (will be used as part of the name of the temp file i.e: cn=Al,o=DEMOCORP,c=AU).
43      * @param entry the actual entry that is being displayed.
44      * @param type the attribute type for example: audio or jpegPhoto.
45      * @param size the size of the number of specific attribute values this entry contains (i.e. 3 jpegPhoto attributes).
46      */

47
48     public static void createCache(String JavaDoc currentDN, Attributes JavaDoc entry, String JavaDoc type, int size)
49     {
50         if (type.equalsIgnoreCase("audio"))
51         {
52             createAudioCache(currentDN, entry, type, size);
53             return;
54         }
55
56         fileDir = makeDir();
57         allFiles = fileDir.list();
58
59         currentDN = Integer.toString(currentDN.hashCode());
60
61         for (int i = 0; i < allFiles.length; i++) //TE: don't create temporary files if they already exist for the entry.
62
{
63             if (allFiles[i].startsWith(currentDN) && type.equalsIgnoreCase("jpegPhoto") && allFiles[i].endsWith(".jpg"))
64                 return;
65             else if (allFiles[i].startsWith(currentDN) && type.equalsIgnoreCase("odDocumentDOC") && allFiles[i].endsWith(".doc"))
66                 return;
67             else if (allFiles[i].startsWith(currentDN) && type.equalsIgnoreCase("odSpreadSheetXLS") && allFiles[i].endsWith(".xls"))
68                 return;
69             else if (allFiles[i].startsWith(currentDN) && type.equalsIgnoreCase("odMovieAVI") && allFiles[i].endsWith(".avi"))
70                 return;
71             else if (allFiles[i].startsWith(currentDN) && type.equalsIgnoreCase("odSoundWAV") && allFiles[i].endsWith(".wav"))
72                 return;
73             else if (allFiles[i].startsWith(currentDN) && type.equalsIgnoreCase("odMusicMID") && allFiles[i].endsWith(".mid"))
74                 return;
75         }
76
77         for (int i = 0; i < size; i++)
78         {
79             byte[] bytes = getAttByteValue(type, entry, i); //TE: gets the byte[] of the jpegPhoto/audio attribute.
80

81             if (type.equalsIgnoreCase("odDocumentDOC"))
82             {
83                 doNormalCache(currentDN, bytes, ".doc");
84             }
85             else if (type.equalsIgnoreCase("odSpreadSheetXLS"))
86             {
87                 doNormalCache(currentDN, bytes, ".xls");
88             }
89             else if (type.equalsIgnoreCase("odMovieAVI"))
90             {
91                 doNormalCache(currentDN, bytes, ".avi");
92             }
93             else if (type.equalsIgnoreCase("odMusicMID"))
94             {
95                 doNormalCache(currentDN, bytes, ".mid");
96             }
97             else if (type.equalsIgnoreCase("odSoundWAV"))
98             {
99                 doNormalCache(currentDN, bytes, ".wav");
100             }
101             else if (type.equalsIgnoreCase("jpegPhoto"))
102             {
103                 doNormalCache(currentDN, bytes, ".jpg");
104             }
105         }
106         if (allFiles.length > CACHEMAX) //TE: decrease the size of the cache if the cache contains 100 or more temporary files.
107
decreaseCacheSize();
108     }
109
110
111     /**
112      * Creates an audio cache directory named 'temp/audio' and adds temporary files to it currently naming
113      * them (for example) with the hash of their 'DN + a unique number + .wav'.
114      *
115      * @param currentDN the dn of the entry being modified (will be used as part of the name of the temp file i.e: cn=Al,o=DEMOCORP,c=AU).
116      * @param entry the actual entry that is being displayed.
117      * @param type the attribute type for example: audio or jpegPhoto.
118      * @param size the size of the number of specific attribute values this entry contains (i.e. 3 audio attributes).
119      */

120
121     public static void createAudioCache(String JavaDoc currentDN, Attributes JavaDoc entry, String JavaDoc type, int size)
122     {
123         if (!type.equalsIgnoreCase("audio"))
124         {
125             log.warning("Error - trying to create a audio temporary cache with incorrect data in 'CBCache.createAudioCache'.");
126             return;
127         }
128
129         audioFileDir = makeAudioDir();
130         allAudioFiles = audioFileDir.list();
131
132         currentDN = Integer.toString(currentDN.hashCode());
133
134         for (int i = 0; i < allAudioFiles.length; i++) //TE: don't create temporary files if they already exist for the entry.
135
{
136             if (allAudioFiles[i].startsWith(currentDN))
137                 return;
138         }
139
140         for (int i = 0; i < size; i++)
141         {
142             byte[] bytes = getAttByteValue(type, entry, i); //TE: gets the byte[] of the jpegPhoto/audio attribute.
143

144             if (type.equalsIgnoreCase("audio"))
145             {
146                 doAudioCache(currentDN, bytes);
147             }
148         }
149         if (allAudioFiles.length > CACHEMAX) //TE: decrease the size of the cache if the cache contains 100 or more temporary files.
150
decreaseAudioCacheSize();
151     }
152
153
154     /**
155      * Does the actual writing of the cache files.
156      *
157      * @param currentDN the dn of the entry being modified (will be used as part of the name of the temp file i.e: cn=Al,o=DEMOCORP,c=AU).
158      * @param bytes the byte[] of the audio attribute.
159      * @param extension the extension of the cache file (currently .doc, .jpg).
160      */

161
162     public static void doNormalCache(String JavaDoc currentDN, byte[] bytes, String JavaDoc extension)
163     {
164         String JavaDoc name = currentDN + counter + extension;
165         File file = new File(fileDir, name);
166
167         counter++;
168
169         try
170         {
171             file.deleteOnExit(); //TE: deletes the temporary files when JX is shut down.
172

173             FileOutputStream output = new FileOutputStream(file);
174             output.write(bytes);
175             output.close();
176         }
177         catch (Exception JavaDoc e)
178         {
179             CBUtility.error(CBIntText.get("Problem writing the temporary file: ") + file.toString() + "\n" + e);
180         }
181     }
182
183
184     /**
185      * Creates the audio temporary files. First, the type of audio file needs to be determined.
186      * This is done by converting the first 100 bytes of the audio file to hex then searching it for an
187      * identifier of the audio file (for example in a .wav file the header should contain the word 'WAVE'
188      * which in hex is '574156'). If the audio file type is determined the temporary file is created with
189      * the current DN + a unique number + the extension for example:
190      * <p/>
191      * cn=Al,o=DEMOCORP,c=AU9.wav
192      * <p/>
193      * This method can determine the following audio file types:
194      * <p/>
195      * .wav
196      * .mp3
197      * .rmi
198      * .ram
199      * .aiff
200      * .mid
201      * .au
202      * .stm
203      * .voc
204      * .xm
205      * .s3m
206      * .it
207      * <p/>
208      * if an audio file type is unknown the temporary file is still created but with no extension.
209      *
210      * @param currentDN the dn of the entry being modified (will be used as part of the name of the temp file i.e: cn=Al,o=DEMOCORP,c=AU).
211      * @param bytes the byte[] of the audio attribute.
212      */

213
214     public static void doAudioCache(String JavaDoc currentDN, byte[] bytes)
215     {
216         byte[] testBytes = new byte[100];
217         if (bytes.length > 100)
218             System.arraycopy(bytes, 0, testBytes, 0, 100);
219         else
220             testBytes = bytes;
221
222         String JavaDoc hexSub = CBParse.bytes2Hex(testBytes);
223
224         //TE: look at the header of the sound files and determine the extension.
225
if (hexSub.indexOf("574156") > -1)
226             extension = ".wav";
227         else if (hexSub.indexOf("494433") > -1)
228             extension = ".mp3";
229         else if ((hexSub.toLowerCase()).indexOf("fffb9044") > -1)
230             extension = ".mp3";
231         else if ((hexSub.toLowerCase()).indexOf("fffb300c") > -1)
232             extension = ".mp3";
233         else if ((hexSub.toLowerCase()).indexOf("fff330c0") > -1)
234             extension = ".mp3";
235         else if (hexSub.indexOf("524946") > -1)
236             extension = ".rmi";
237         else if ((hexSub.toLowerCase()).indexOf("524d46") > -1)
238             extension = ".ram";
239         else if (hexSub.indexOf("41494646") > -1)
240             extension = ".aiff";
241         else if ((hexSub.toLowerCase()).indexOf("4d546864") > -1)
242             extension = ".mid";
243         else if ((hexSub.toLowerCase()).indexOf("2e736e64") > -1)
244             extension = ".au";
245         else if ((hexSub.toLowerCase()).indexOf("636f6f6c") > -1)
246             extension = ".stm"; //TE: screamTracker format.
247
else if ((hexSub.toLowerCase()).indexOf("437265617469766520566f6963652046696c65") > -1)
248             extension = ".voc"; //TE: Creative Voice File.
249
else if ((hexSub.toLowerCase()).indexOf("457874656e646564204d6f64756c65") > -1)
250             extension = ".xm"; //TE: Extended Module format.
251
else if ((hexSub.toLowerCase()).indexOf("5343524d") > -1)
252             extension = ".s3m";
253         else if ((hexSub.toLowerCase()).indexOf("494d50") > -1)
254             extension = ".it";
255         else
256             extension = ".xxx";
257
258         File file = new File(audioFileDir, currentDN + counter + extension);
259         counter++;
260
261         file.deleteOnExit(); //TE: deletes the temporary files when JX is shut down.
262
try
263         {
264             FileOutputStream output = new FileOutputStream(file);
265             output.write(bytes);
266             output.close();
267         }
268         catch (IOException e)
269         {
270             CBUtility.error(CBIntText.get("Problem writing the audio temporary file: ") + file.toString() + "\n" + e);
271         }
272     }
273
274
275     /**
276      * This Comparator compares two Files by their lastModified() date.
277      */

278
279     public static class FileComparator implements Comparator JavaDoc
280     {
281         /**
282          * This Comparator compares two Files by their lastModified() date.
283          *
284          * @param o1 one of the two items to be compared.
285          * @param o2 the other of the items to be compared.
286          */

287
288         public int compare(Object JavaDoc o1, Object JavaDoc o2)
289         {
290             long a = ((File) o1).lastModified();
291             long b = ((File) o2).lastModified();
292
293             return (a == b) ? 0 : ((a < b) ? -1 : 1);
294         }
295     }
296
297
298     /**
299      * Sorts an array of files in order of lastModified (oldest to newest).
300      *
301      * @param files the array of files to be sorted.
302      * @return the sorted file array.
303      */

304
305     public static File[] sortFiles(File[] files)
306     {
307         Arrays.sort(files, new FileComparator());
308         return files;
309     }
310
311
312     /**
313      * Returns the directory that is being used for the caching.
314      *
315      * @return the directory.
316      */

317
318     public static File getCacheDirectory()
319     {
320         return fileDir;
321     }
322
323
324     /**
325      * Returns the directory that is being used for the audio caching.
326      *
327      * @return the directory.
328      */

329
330     public static File getAudioCacheDirectory()
331     {
332         return audioFileDir;
333     }
334
335
336     /**
337      * Decreases the size of the cache (usually if the cache contains 100 or more temporary files),
338      * by deleting the oldest files until there is only 50 temporary files left in the cache.
339      * It also checks that it deletes all the files pertaining to one entry i.e. if an entry has
340      * four temporary files, this method will try to delete all four even if the minimum level of 50 is
341      * reached (this ensures that the templates refresh correctly).
342      */

343
344     public static void decreaseCacheSize()
345     {
346         File[] fileArray = fileDir.listFiles();
347
348         fileArray = sortFiles(fileArray); //TE: sort the files according to there last modified date (oldest to newest).
349

350         for (int i = 0; i < (fileArray.length - CACHEMIN); i++) //TE: do the following until there is only 50 temp files left.
351
{
352             String JavaDoc fileName = fileArray[i].getName();
353
354             for (int x = 0; x < allFiles.length; x++) //TE: make sure that when deleting a temp file, that all the temp files pertaining to the same entry are deleted also.
355
{
356                 if (allFiles[x].startsWith(fileName.substring(0, ((fileArray[i].toString()).length()) - 15)))
357                 {
358                     //TE: if the temp file in the directory at position 'x' starts with the the same name as the temp file listed at
359
// position i of the sorted array (sorted by last modified), minus the last 15 characters (to ensure that the
360
// 'digit+.extension' is cut off the temp name), then delete it!...phew
361

362                     File tempFile = new File(makeDir(), allFiles[x].toString());
363                     tempFile.delete();
364                 }
365             }
366         }
367         decreaseAudioCacheSize();
368     }
369
370
371     /**
372      * Decreases the size of the audio cache (usually if the cache contains 100 or more temporary files),
373      * by deleting the oldest files until there is only 50 temporary files left in the cache.
374      * It also checks that it deletes all the files pertaining to one entry i.e. if an entry has
375      * four temporary files, this method will try to delete all four even if the minimum level of 50 is
376      * reached (this ensures that the templates refresh correctly).
377      */

378
379     public static void decreaseAudioCacheSize()
380     {
381         File[] fileArray = audioFileDir.listFiles();
382
383         fileArray = sortFiles(fileArray); //TE: sort the files according to there last modified date (oldest to newest).
384

385         for (int i = 0; i < (fileArray.length - CACHEMIN); i++) //TE: do the following until there is only 50 temp files left.
386
{
387             String JavaDoc fileName = fileArray[i].getName();
388
389             for (int x = 0; x < allAudioFiles.length; x++) //TE: make sure that when deleting a temp file, that all the temp files pertaining to the same entry are deleted also.
390
{
391                 if (allAudioFiles[x].startsWith(fileName.substring(0, ((fileArray[i].toString()).length()) - 15)))
392                 {
393                     //TE: if the temp file in the directory at position 'x' starts with the the same name as the temp file listed at
394
// position i of the sorted array (sorted by last modified), minus the last 15 characters (to ensure that the
395
// 'digit+.extension' is cut off the temp name), then delete it!...phew
396

397                     File tempFile = new File(makeAudioDir(), allAudioFiles[x].toString());
398                     tempFile.delete();
399                 }
400             }
401         }
402     }
403
404
405     /**
406      * Creates the temporary directory, calling it 'temp'.
407      *
408      * @return the directory.
409      */

410
411     private static File makeDir()
412     {
413         File dir = new File(dirPath);
414         dir.mkdir();
415         dir.deleteOnExit();
416
417         return dir;
418     }
419
420
421     /**
422      * Creates the temporary audio directory, calling it 'temp/audio'.
423      *
424      * @return the directory.
425      */

426
427     private static File makeAudioDir()
428     {
429         File dir = new File(dirPath + File.separator + "audio");
430         dir.mkdir();
431         dir.deleteOnExit();
432
433         return dir;
434     }
435
436
437     /**
438      * Returns the absolute path of the temp directory.
439      *
440      * @return the path of the temp directroy.
441      */

442
443     public static String JavaDoc getDirPath()
444     {
445         return makeDir().getAbsolutePath();
446     }
447
448
449     /**
450      * Sets the path of the temp directory.
451      *
452      * @param path the path of where to make the temp directory
453      */

454
455     public static String JavaDoc setDirPath(String JavaDoc path)
456     {
457         return dirPath = path;
458     }
459
460
461     /**
462      * Returns the absolute path of the audio temp directory.
463      *
464      * @return the path of the temp directroy.
465      */

466
467     public static String JavaDoc getAudioDirPath()
468     {
469         return makeAudioDir().getAbsolutePath();
470     }
471
472
473     /**
474      * Gets the byte[] value of a specified attribute value.
475      *
476      * @param name the name of the attribute value e.g. 'jpegPhoto'.
477      * @param entry the entry that is to be displayed.
478      * @param entries the number of attributes values (e.g. 'jpegPhoto') pertaining to the entry.
479      * @return the byte array of the attribute value.
480      */

481
482     private static byte[] getAttByteValue(String JavaDoc name, Attributes JavaDoc entry, int entries)
483     {
484         try
485         {
486             Attribute JavaDoc a = entry.get(name);
487             if (a == null) return null; // no pre-existing value, so nothing to do.
488
if (a.size() == 0 || a.get() == null) return null; // no pre-existing value, so nothing to do.
489

490             Object JavaDoc o = a.get(entries); //TE: gets the attribute value at a certain position i.e. if 3 attribute values it will get the one at the position stored in entires.
491

492             if (o instanceof byte[])
493                 return (byte[]) o;
494
495             return null;
496         }
497         catch (NamingException JavaDoc e)
498         {
499             log.log(Level.WARNING, "Form Value Error getting value for " + name + " value :\n ", e); // not a terminal error.
500
return null;
501         }
502     }
503
504
505     /**
506      * Cleans the cache of entries that start with the dn of the entry being modified.
507      *
508      * @param currentDN the dn of the entry being modified.
509      */

510
511     public static void cleanCache(String JavaDoc currentDN)
512     {
513         currentDN = Integer.toString(currentDN.hashCode());
514
515         allFiles = makeDir().list();
516
517         for (int i = 0; i < allFiles.length; i++)
518         {
519             if (allFiles[i].startsWith(currentDN.toString())) //&& allFiles[i].endsWith(extension)) //TE: check that the temp files are of the entry being modified.
520
{
521                 File tempFile = new File(fileDir, allFiles[i].toString());
522                 tempFile.delete();
523             }
524         }
525
526         allAudioFiles = makeAudioDir().list();
527
528         for (int i = 0; i < allAudioFiles.length; i++)
529         {
530             if (allAudioFiles[i].startsWith(currentDN.toString())) //&& allFiles[i].endsWith(extension)) //TE: check that the temp files are of the entry being modified.
531
{
532                 File tempFile = new File(audioFileDir, allAudioFiles[i].toString());
533                 tempFile.delete();
534             }
535         }
536     }
537
538
539     /**
540      * Cleans the cache of all temporary entries by deleting them.
541      */

542
543     public static void cleanCache()
544     {
545         allFiles = makeDir().list();
546
547         if (allFiles == null)
548             return;
549
550         for (int i = 0; i < allFiles.length; i++)
551         {
552             File tempFile = new File(makeDir(), allFiles[i].toString());
553             tempFile.delete();
554         }
555
556         allAudioFiles = makeAudioDir().list();
557
558         for (int i = 0; i < allAudioFiles.length; i++)
559         {
560             File tempFile = new File(makeAudioDir(), allAudioFiles[i].toString());
561             tempFile.delete();
562         }
563     }
564
565
566     /**
567      * Sets the maximum cache size @CACHEMAX@
568      *
569      * @param size the maximum cache size.
570      */

571
572     public static void setMaxCacheSize(int size)
573     {
574         CACHEMAX = size;
575     }
576
577
578     /**
579      * Sets the minimum cache size @CACHEMAX@
580      *
581      * @param size the minimum cache size.
582      */

583
584     public static void setMinCacheSize(int size)
585     {
586         CACHEMIN = size;
587     }
588
589 }
Popular Tags