001/* 002$Source: f:/cvsroot2/open/projects/WebARTS/ca/bc/webarts/widgets/DirReadBean.java,v $ 003$Name: $ 004 005$Revision: 567 $ 006$Date: 2012-11-03 20:36:02 -0700 (Sat, 03 Nov 2012) $ 007$Locker: $ 008*/ 009 010/* DirReadBean -- A Widget Class to do some cool formating of Directory info. 011 * 012 * Copyright (C) 2001 WebARTS Design, North Vancouver Canada 013 * http://www..webarts.bc.ca 014 * 015 * This program is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU General Public License as published by 017 * the Free Software Foundation; either version 2 of the License, or 018 * (at your option) any later version. 019 * 020 * This program is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU General Public License for more details. 024 * 025 * You should have received a copy of the GNU General Public License 026 * along with this program; if not, write to the Free Software 027 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 028 */ 029 030package ca.bc.webarts.widgets; 031 032import java.io.File; 033import java.io.FileReader; 034import java.io.FileNotFoundException; 035import java.io.IOException; 036import java.io.FileWriter; 037import java.util.Hashtable; 038import java.util.HashMap; 039import java.util.Iterator; 040import java.util.TreeSet; 041import java.util.Vector; 042import java.lang.System; 043 044 045/** 046 * A Widget that does some directory reading, filtering and presents some 047 * useful HTML displayed information about the files. 048 **/ 049public class DirReadBean { 050 051 052/** holds a String message of the last error that occured **/ 053private static String lastErrorMsg=""; 054 055 056static final private String defaultDirString = File.separator ; 057 058 059/** The directory being worked on as a <code>String</code>. **/ 060private static String dirString = defaultDirString + "testDir" ; 061 062 063/** the directory being worked on as a <code>File</code>. **/ 064private File dirFile = null; 065 066 067/** 068 * This String holds the results of any parsing and filtering that is 069 * performed. It will hold an html presentation of the directory. 070 **/ 071private String outText_; 072 073 074/** A list of filenames in the current dir. **/ 075private static String [] fileName = null; 076 077/** A list of filenames path from the current dir. **/ 078private static String [] fileNamePath = null; 079 080 081/** A index refernce to the current file we are dealing with. **/ 082private static short fileIndex =0; 083 084 085/** the number of files in the current <code>dirFile</code> directory. **/ 086private static short numFiles = 0; 087 088private HashMap magMap = new HashMap(); 089 090/** Holds the Long size info for each file in <code>fileName[]</code>.**/ 091private Hashtable fileSizeHash = new Hashtable(); 092 093private static long totalFileSize= 0L; 094 095private String winampFilename = "DirectoryWinAmpList.m3u"; 096 097 098/** Sets the String holding the directory this class is working on. **/ 099public static void setDirString(String s){dirString = s;} 100 101 102/** Sets the String holding the current HTML output string. **/ 103protected void setOutText(String s){outText_ = s;} 104 105 106/** Gets the String holding the current HTML output string. **/ 107public String getOutText(){return outText_;} 108 109 110/** 111 * Directly sets the dirFile we are working on. 112 * <P>The preferred way of setting this is with the <code>initDirFile</code> 113 * method. 114 * 115 * @param f the File to set dirFile to. 116 * @see #initDirFile(String) 117 **/ 118protected void setDirFile(File f){dirFile = f;} 119 120 121/** Gets the dirFile we are working on. **/ 122public File getDirFile(){return dirFile;} 123 124 125/** 126 * Initisalizes the dirFile field with a new File represented by the passed in 127 * String 128 **/private boolean initDirFile(String s) 129{ 130 boolean retVal = false; 131 dirFile = new File(s); 132 if(dirFile.isDirectory() && dirFile.canRead()) 133 retVal = true; 134 return retVal; 135} 136 137 138public int getNumFiles(){return numFiles;} 139 140 141/** 142 * Reads the Dir and Inits all required class data. 143 * 144 * @param s is the dir to init. 145 **/ 146public boolean initDir(String s) 147{ 148 initFileIndex(); 149 return initDir(s, false); 150} 151 152 153/** 154 * Reads the Dir and Inits all required class data. 155 * 156 * @param s is the dir to init. 157 * @param recurse specifies if it should recurse for files. 158 **/ 159public boolean initDir(String s, boolean recurse) 160{ 161 initFileIndex(); 162 return initDir(s,"",recurse); 163} 164 165 166/** 167 * Reads the Dir and Inits all required class data. 168 * 169 * @param s is the dir to init. 170 * @param subPath is the dir path to prepend to the filenames. 171* @param recurse specifies if it should recurse for files. 172 **/ 173public boolean initDir(String s, String subPath, boolean recurse) 174{ 175 boolean retVal = initDirFile(s); 176 if (retVal) 177 { 178 initFileIndex(); 179 File tempFile; 180 System.out.println("Initing a dir - dirString = "+dirString+". s="+s+". "); 181 numFiles = 0; 182 initFileIndex(); 183 if (!dirString.equals(s)) 184 { 185 setDirString(s); 186 } 187 String[] currentDirfiles = dirFile.list(); 188 189 // count how many files and init our array 190 if (numFiles == 0) 191 for (int i=0; i< currentDirfiles.length; i++) 192 { 193 tempFile = new File(dirString+File.separator+currentDirfiles[i]); 194 if(!tempFile.isDirectory()) 195 { 196 //System.out.println("Counting File "+ 197 // dirString+File.separator+currentDirfiles[i]); 198 numFiles++; 199 } 200 else if (recurse) 201 numFiles += 202 Util.countFilesInDir(dirString+File.separator+currentDirfiles[i], 203 true); 204 } 205 //if (fileName == null) 206 //{ 207 System.out.println("numFiles = "+numFiles); 208 fileName = new String[numFiles]; //dirFile.list(); 209 fileNamePath = new String[numFiles]; 210 //} 211 212 for (int i=0; i< currentDirfiles.length; i++) 213 { 214 if (i==0) 215 System.out.println("Start Of Processing: "+currentDirfiles.length+ 216 "/"+fileIndex+"/"+numFiles); 217 tempFile = new File(dirString+File.separator+currentDirfiles[i]); 218 if(!tempFile.isDirectory()) 219 { 220 fileName[fileIndex] = currentDirfiles[i]; 221 fileNamePath[fileIndex] = subPath; 222 223 fileSizeHash.put(fileName[fileIndex++] , 224 new Long( (long) tempFile.length())); 225 totalFileSize += (long) tempFile.length(); 226 } 227 else if (recurse) 228 { 229 String recursedSubpath = currentDirfiles[i]; 230 if (subPath != null && subPath.length()>0) 231 recursedSubpath = subPath+"/"+currentDirfiles[i]; 232 //System.out.println("Recurse on = "+tempFile.toString()); 233 initDir(tempFile.toString(), recursedSubpath,true); 234 //System.out.println(fileIndex); 235 initDirFile(s); 236 setDirString(s); 237 currentDirfiles = dirFile.list(); 238 //System.out.println(fileIndex); 239 } 240 } 241 System.out.println("End Of Processing: "+currentDirfiles.length+ 242 "/"+fileIndex+"/"+numFiles); 243 244 //initFileIndex(); 245 } 246 return retVal; 247} 248 249 250public void initOutText(){outText_ = "<html><body>\n"; } 251public static void initFileName(){fileName=null;} 252public static void initFileIndex(){fileIndex=0;} 253public void appendOutText(String s) {outText_ += s;} 254public void finalizeOutText(){outText_ += "\n</body></html>"; } 255public String getDirString(){return dirString;} 256public static String getLastErrorMessage(){ return lastErrorMsg;} 257public Long getTotalFileSize(){return new Long(totalFileSize);} 258 259/** 260 * Gets the file size for the file name passed in form the passed in 261 *dirString directory. 262 * 263 * @param dirString the string representation of the directory. 264 * @param s the string representation of the filename to lookup. 265 * @return the Long representing the requested file size. 266 **/ 267public Long getFileSize(String dirString, String s) 268{ 269 initDir(dirString); 270 return ((Long)fileSizeHash.get(s)); 271} 272 273 274/** 275 * Gets the file size for the file name passed in.<P> It looks up the values in 276 * this classes Hash of the filenames... soi the readDir method or the 277 * initDir methodMUST be called before this method to ensure that the hash is 278 * initialized with the current directory info. 279 * <P>See also the getFileSize(String, String) method that takes 280 * the dir as well so you don't have to call readDir first 281 * 282 * @param s the string representation of the filename to lookup. 283 * @return the Long representing the requested file size. 284 **/ 285public Long getFileSize(String s) 286{ 287 return ((Long)fileSizeHash.get(s)); 288} 289 290 291/** 292 * A helper method to abstract the work to find out if a file exists. 293 * 294 * @param s the string representing the file name to look for. 295 * 296 * @return true if the file exists, false if it doesn't. duh. 297 **/ 298public boolean doesFileExist(String s) 299{ 300 boolean retVal = false; 301 try 302 { 303 FileReader testFile = new FileReader(getDirString()+File.separator+s); 304 retVal = true; 305 lastErrorMsg = "doesFileExist: NoError: filename="+s; 306 } 307 catch (java.io.FileNotFoundException nfEx) 308 { 309 retVal = false; 310 lastErrorMsg = "doesFileExist: filename=" + s + 311 " File NOT Found Exception"; 312 } 313 catch (SecurityException secEx) 314 { 315 retVal = false; 316 lastErrorMsg = "doesFileExist: SecurityException: filename=" + s; 317 } 318 return retVal; 319} 320 321 322/** 323 * Looks up the next file in the indexed list of files being kept by this class. 324 * 325 * @return a string representin the name of the next file in the file list. 326 **/ 327public String getNextFileName() 328{ 329 String retVal = null; 330 if (fileIndex<numFiles) 331 retVal = fileName[fileIndex++] ; 332 return retVal; 333} 334 335 336/** 337 * Looks up the next file path in the indexed list of files being kept by this class. 338 * 339 * @return a string representin the name of the next file in the file list. 340 **/ 341public String getNextFilePath() 342{ 343 String retVal = null; 344 if (fileIndex<numFiles) 345 retVal = fileNamePath[fileIndex] ; 346 return retVal; 347} 348 349 350/** 351 * Looks up the next file in the indexed list of files and returns its size. 352 * 353 * @return a Long representing the filesaize of the next file in the file list. 354 **/ 355public Long getNextFileSize() 356{ 357 Long retVal = new Long(-1L); 358 if (fileIndex<numFiles) 359 retVal = getFileSize(fileName[fileIndex]) ; 360 return retVal; 361} 362 363 364public String getFileContents(String s){ 365 String retVal = ""; 366 try{ 367 StringBuffer sBuf = new StringBuffer(); 368 int numChars=0; 369 FileReader fileReader = new FileReader(getDirString()+File.separator+s); 370 byte tempChar = (byte) fileReader.read(); 371 while (tempChar != -1) { 372 sBuf.append( (char) tempChar); 373 tempChar =(byte) fileReader.read(); 374 } 375 retVal = sBuf.toString(); 376 } 377 catch (FileNotFoundException fnfEx){ 378 retVal = "File" +s + " NOT Found."; 379 } 380 catch (SecurityException secEx){ 381 retVal = "Unable To Read File " +s +": Security."; 382 } 383 catch (IOException ioEx){ 384 retVal = "Unable To Read File " +s +": IO Error."; 385 } 386 return retVal; 387} 388 389 390/** 391 * Removes any space chars ' ' from a filename and Capitalizes the next char. 392 * <P><B>NOTE:</B> The file is expected to be in 393 * the current working directorydirectory 394 * 395 * @param dirString the directory to look in for the file name (no trailing /). 396 * @param fName a string representing the file to perform the action. 397 * @return the new filename representation 398 **/ 399public String spacesToCapsInFileName(String dirString, String fName) 400{ 401 setDirString(dirString); 402 return spacesToCapsInFileName(fName); 403} 404 405 406/** 407 * Removes any space chars ' ' from a filename and Capitalizes the next char. 408 * <P><B>NOTE:</B> The file is expected to be in 409 * the current working directorydirectory 410 * 411 * @param fName a string representing the file to perform the action 412 * @return the new filename representation 413 **/ 414public String spacesToCapsInFileName(String fName) 415{ 416 String newName = ""; 417 File tempFile; 418 if (fileName != null){ 419 tempFile = new File(dirString+File.separator+fName); 420 if(!tempFile.isDirectory()) 421 { 422 boolean space = false; 423 for (int j=0; j< fName.length(); j++) 424 { 425 char newChar = fName.charAt(j); 426 if (newChar == ' ') 427 { 428 // set the space flag so the next char can be cap'd 429 space = true; 430 } 431 else 432 { 433 if (space) // was the last char a space??? 434 { 435 newName += String.valueOf(Character.toUpperCase(newChar)); 436 } 437 else 438 { 439 newName += String.valueOf(newChar); 440 } 441 space = false; 442 } 443 } 444 } 445 } 446 return newName; 447} 448 449 450/** 451 * Renames files to a more URL friendly format. 452 * <P>It goes through each file in the current working directory and renames it 453 * using the spacesToCapsInFileName method of renaming. 454 * 455 * @see #spacesToCapsInFileName(String) 456 * @see #dirFile 457 **/ 458public void autoFormatFileNames() 459{ 460 System.out.println("Formatting dir="+dirFile.toString()); 461 if (dirFile != null && 462 dirFile.isDirectory() && 463 dirFile.canRead() && 464 fileName != null ) 465 { 466 File tempFile; 467 boolean succeeded = false; 468 for (int i=0;i< fileName.length;i++) 469 { 470 tempFile = new File(dirString+File.separator+fileName[i]); 471 String newName = spacesToCapsInFileName(fileName[i]); 472 try 473 { 474 if (newName !="" && fileName[i].length() != newName.length()) 475 { 476 System.out.println(i+".1) "+tempFile.toString()); 477 System.out.print(i+".2) "+dirString+File.separator+newName); 478 succeeded = tempFile.renameTo( 479 new File(dirString+File.separator+newName)); 480 if (succeeded) 481 System.out.print(" succeeded."); 482 else 483 System.out.println(""); 484 File tempFile2 = new File(dirString+File.separator+fileName[i]); 485 if (tempFile2.exists() && 486 tempFile.exists() && 487 !newName.toUpperCase().equals(fileName[i].toUpperCase())) 488 { 489 tempFile2.delete(); 490 } 491 } 492 } 493 catch (SecurityException ex) 494 { 495 System.err.println("SecurityException " + ex); 496 } 497 catch (NullPointerException ex) 498 { 499 System.err.println("NullPointerException " + ex); 500 } 501 } //loop 502 } 503} 504 505 506/** 507 * Formats the files in the directory specified by the passed in String. 508 * <P>This method takes a string representing the directory to use as the basis 509 * for all formatting and then performs the formatting as specified by the 510 * autoFormatFileNames() method.<P><B><U>WARNING:</U></B> This method WRITES to 511 * the directory. It actually changes the names of the files. 512 * 513 * @param arg a string representation of thre directory to parse. 514 * @see #autoFormatFileNames() 515 **/ 516public void autoFormatFileNames(String arg) 517{ 518 // parse the input parms to switch the dir we want 519 if(arg!=null) dirString = arg; 520 521 initOutText(); 522 initDirFile(dirString); 523 if(dirFile.isDirectory()) 524 { 525 if(dirFile.canRead()) 526 { 527 fileName = dirFile.list(); 528 } 529 } 530 autoFormatFileNames(); 531} 532 533public String[] getArtistsNames() 534{ 535 TreeSet magSet = new TreeSet(magMap.keySet()); 536 String [] retVal = new String[magMap.size()]; 537 int ii = 0; 538 for (Iterator i=magSet.iterator(); i.hasNext() ;) 539 { 540 retVal[ii++] = ((String) i.next()).trim(); 541 } 542 return retVal; 543} 544 545public String getWinampFilename() { return winampFilename;} 546public void setWinampFilename(String s) { winampFilename = s;} 547 548 549 550/** 551 * Parse the current directory for files with the spec'd extension and create a 552 * sorted and titled list of Authored entries (mp3 files, pdf magazines etc). 553 * <P>The filenames must be in the format "Author_Title.extension" for this 554 * method to create a decent list. It groups all files withthe same author into 555 * a titled group. 556 * 557 * @param fileExtension the file extension to use as the filter for this list 558 * (without the leading period... 559 * example: for tbg_doc.pdf pass in pdf) 560 * @param filesToIgnore the filenames (without the extension) to not process 561 * @return a string holding the html unordered list 562 **/ 563public String getTitledAuthorList(String fileExtension, 564 String pathPrefix, 565 Vector filesToIgnore) 566{ 567 String retVal = "<!-- - - - - - - - - - - - - - - - - - - - - - - - - -->\n"; 568 retVal += "<!-- Java Servlet Created List - - - - - - - - - - - -->\n"; 569 retVal += "<!-- - - - - - - - - - - - - - - - - - - - - - - - - -->\n"; 570 String name1, name, artist, title; 571 String tempArtist="",expandedTitle,expandedArtist=""; 572 int startPosition, endPosition; 573 Long fileSize, zeroL = new Long(0L); 574 Vector currentMagTitles = null; 575 String [] magTitleInfo = new String[4]; 576 577 initFileIndex(); 578 579 fileSize = zeroL; 580 fileSize = getNextFileSize(); 581 String nextPath = getNextFilePath(); 582 name = getNextFileName(); 583 584 while( name != null ) 585 { 586 if( name.endsWith("."+fileExtension) && 587 (filesToIgnore == null || 588 !filesToIgnore.contains( 589 name.substring(0,name.lastIndexOf("."+fileExtension))))) 590 { 591 expandedTitle=""; 592 startPosition = name.indexOf("_"); 593 if (startPosition < 0 ) 594 { 595 startPosition = 0; 596 artist = "No Title"; 597 } 598 else 599 artist = name.substring(0,startPosition).trim(); 600 601 endPosition = name.lastIndexOf("."+fileExtension); 602 title = name.substring(startPosition+1,endPosition); 603 int len = title.length(); 604 boolean capital = true; 605 boolean letter = true; 606 boolean digit = false; 607 boolean lastDigit = false; 608 char c; 609 for (int i=0;i<len;i++) 610 { 611 c = title.charAt(i); 612 letter = Character.isLetter(c); 613 capital= letter & Character.isUpperCase(c); 614 digit = Character.isDigit(c); 615 616 if (capital || (digit && !lastDigit) || (!digit && !letter)) 617 expandedTitle += " "; 618 619 expandedTitle += c; 620 lastDigit = digit; 621 } 622 if (!(tempArtist.toUpperCase().equals(artist.toUpperCase())) ) 623 { 624 expandedArtist=""; 625 tempArtist = artist; 626 capital = true; 627 letter = true; 628 digit = false; 629 lastDigit = false; 630 for (int i=0;i<startPosition;i++) 631 { 632 c = tempArtist.charAt(i); 633 letter = Character.isLetter(c); 634 capital= letter & Character.isUpperCase(c); 635 digit = Character.isDigit(c); 636 637 if (capital || (digit && !lastDigit) || (!digit && !letter)) 638 expandedArtist += " "; 639 640 expandedArtist += c; 641 lastDigit = digit; 642 } 643 } 644 if (magMap.containsKey(expandedArtist.trim())) 645 { 646 currentMagTitles = (Vector) magMap.get(expandedArtist.trim()); 647 } 648 else 649 { 650 currentMagTitles = new Vector(); 651 } 652 magTitleInfo[0] = name; 653 magTitleInfo[1] = expandedTitle; 654 magTitleInfo[2] = String.valueOf(fileSize); 655 magTitleInfo[3] = nextPath; 656 currentMagTitles.add(magTitleInfo.clone()); 657 magMap.put(expandedArtist.trim(),currentMagTitles); 658 } 659 660 fileSize = getNextFileSize(); 661 nextPath = getNextFilePath(); 662 name = getNextFileName(); 663 } 664 665 retVal +="<ul>\n"; 666 // get a set of the keys (expanded artists) 667 // sorted by TreeSet 668 TreeSet magSet = new TreeSet(magMap.keySet()); 669 for (Iterator i=magSet.iterator(); i.hasNext() ;) 670 { 671 expandedArtist = ((String) i.next()).trim(); 672 retVal +="<br /><br /><a name=\"" + expandedArtist + "\">"; 673 retVal +="<b><u>" + expandedArtist + "</u></b></a>"; 674 675 // now get the titles for the mag & sort them 676 currentMagTitles = (Vector)magMap.get(expandedArtist); 677 HashMap sortedTitleMap = new HashMap(); 678 for (int j=0; j<currentMagTitles.size(); j++) 679 { 680 String [] currTitles= (String[]) currentMagTitles.get(j); 681 expandedTitle = currTitles[1]; 682 sortedTitleMap.put(expandedTitle, currTitles); 683 } 684 TreeSet tileSet = new TreeSet(sortedTitleMap.keySet()); 685 String fileSizeStr = ""; 686 String filePathStr = pathPrefix; 687 for (Iterator j=tileSet.iterator(); j.hasNext() ;) 688 { 689 String key = (String) j.next(); 690 String [] currTitles= (String[]) sortedTitleMap.get(key); 691 name = currTitles[0]; 692 expandedTitle = currTitles[1]; 693 fileSizeStr = currTitles[2]; 694 if (currTitles[3] == null || currTitles[3].equals("")) 695 filePathStr =pathPrefix; 696 else 697 filePathStr = currTitles[3]; 698 if (filePathStr == null) 699 filePathStr = ""; 700 701 if (filePathStr != null && 702 filePathStr.length()>0 && 703 !filePathStr.endsWith("/")) 704 filePathStr += "/"; 705 retVal +="<li><a href="+ filePathStr+name + ">" + expandedTitle +"</a>" + 706 " <font size=-1>(<i>" + fileSizeStr + 707 "</i></font> bytes)\n"; 708 } 709 } 710 retVal +="</ul>\n"; 711 712 return retVal; 713} 714 715 716/** 717 * Parse the current directory for files with the spec'd extension and create a 718 * sorted and titled list of Authored entries (mp3 files, pdf magazines etc). 719 * <P>The filenames must be in the format "Author_Title.extension" for this 720 * method to create a decent list. It groups all files withthe same author into 721 * a titled group. 722 * 723 * @param fileExtension the file extension to use as the filter for this list 724 * (without the leading period... 725 * example: for tbg_doc.pdf pass in pdf) 726 * @return a string holding the html unordered list 727 **/ 728public String getTitledAuthorList(String fileExtension) 729{ 730 return getTitledAuthorList(fileExtension, "", null); 731} 732 733 734/** 735 * Parse the current directory for files with the spec'd extension and create a 736 * sorted and titled list of Authored entries (mp3 files, pdf magazines etc). 737 * <P>The filenames must be in the format "Author_Title.extension" for this 738 * method to create a decent list. It groups all files withthe same author into 739 * a titled group. 740 * 741 * @param fileExtension the file extension to use as the filter for this list 742 * (without the leading period... 743 * example: for tbg_doc.pdf pass in pdf) 744 * @param pathPrefix is the path to prefix each href with 745 * @return a string holding the html unordered list 746 **/ 747public String getTitledAuthorList(String fileExtension, String pathPrefix) 748{ 749 return getTitledAuthorList(fileExtension, pathPrefix, null); 750} 751 752 753/** 754 * Reads the passed in directory and produces HTML representing the directory. 755 * <P>It initializes all the current directory variables for this class so other 756 * helper methods that work on a current directory have valid variables. It 757 * prepares the HTML represerntation of the directory and returns it and also 758 * places it in the outText_ variable. 759 * 760 * @param arg the String representation of the directory to read. 761 * @return the HTML representation of the directory. 762 **/ 763public String readDir(String arg) 764{ 765 // parse the input parms to switch the dir we want 766 if(arg!=null) setDirString(arg); 767 768 initOutText(); 769 initDirFile(dirString); 770 if(dirFile.isDirectory()) 771 { 772 if(dirFile.canRead()) 773 { 774 String[] files = dirFile.list(); 775 fileName = dirFile.list(); 776 File tempFile; 777 for (int i=0;i< fileName.length;i++) 778 { 779 outText_ += "<UL>\n"; 780 tempFile = new File(dirString+File.separator+files[i]); 781 if(tempFile.isDirectory()) 782 outText_ += "<LI> [DIR] <A HREF=\""+files[i]+"\">" + 783 files[i] + "</A> <FONT size=\"-1\">(<I>" + tempFile.length() + 784 " bytes</I>)</font>"; 785 else 786 { 787 outText_ += "<LI> <A HREF=\""+files[i]+"\">" + 788 files[i] + "</A> <FONT size=\"-1\">(<I>" + tempFile.length() + 789 " bytes</I>)</font>"; 790 fileName[fileIndex] = files[i]; 791 fileSizeHash.put(fileName[fileIndex++] , 792 new Long( (long) tempFile.length())); 793 794 } 795 outText_+="</UL>\n"; 796 } 797 numFiles = fileIndex; 798 //initFileIndex(); 799 } 800 else { 801 outText_ += "\n<P><B><I>Error Encountered:</I></B>"; 802 outText_ += "\n<P>Unable to read Directory ->" + dirString; 803 outText_ += "\n<HR>"; 804 } 805 } 806 else { 807 outText_ += "\n<P><B><I>Error Encountered:</I></B>"; 808 outText_ += "\n<P>Not A Directory ->" + dirString; 809 outText_ += "\n<HR>"; 810 } 811 812 finalizeOutText(); 813 814 return(outText_); 815} 816 817 818public static synchronized String[] parseAuthorAndTitleFromFilename(String filename) 819{ 820 String[] retVal = new String[2]; 821 822 String author = ""; 823 // Get the Author Name 824 int startPosition = filename.indexOf("_"); 825 if (startPosition < 0 ) 826 { 827 startPosition = 0; 828 author = "Not Available"; 829 } 830 else 831 author = filename.substring(0,startPosition).trim(); 832 833 int endPosition = filename.lastIndexOf("."); 834 835 // get the Title 836 String title = filename.substring(startPosition+1,endPosition); 837 838 839 // now expand the tile and author 840 String tempAuthor=""; 841 String expandedTitle=""; 842 String expandedAuthor=author; 843 int len = title.length(); 844 boolean capital = true; 845 boolean letter = true; 846 boolean digit = false; 847 boolean lastDigit = false; 848 char c; 849 for (int i=0; i<len; i++) 850 { 851 c = title.charAt(i); 852 letter = Character.isLetter(c); 853 capital= letter & Character.isUpperCase(c); 854 digit = Character.isDigit(c); 855 856 if (capital || (digit && !lastDigit) || (!digit && !letter)) 857 expandedTitle += " "; 858 859 expandedTitle += c; 860 lastDigit = digit; 861 } 862 if (!(tempAuthor.toUpperCase().equals(author.toUpperCase())) ) 863 { 864 expandedAuthor=""; 865 tempAuthor = author; 866 capital = true; 867 letter = true; 868 digit = false; 869 lastDigit = false; 870 for (int i=0;i<startPosition;i++) 871 { 872 c = tempAuthor.charAt(i); 873 letter = Character.isLetter(c); 874 capital= letter & Character.isUpperCase(c); 875 digit = Character.isDigit(c); 876 877 if (capital || (digit && !lastDigit) || (!digit && !letter)) 878 expandedAuthor += " "; 879 880 expandedAuthor += c; 881 lastDigit = digit; 882 } 883 } 884 885 retVal[0] = expandedAuthor; 886 retVal[1] = expandedTitle; 887 888 return retVal; 889} 890 891/** 892 * Reads the passed in directory and produces a winamp playlist for all 893 * mp3 and ogg files in the dir. It returns a playlist string. 894 * 895 * @param urlRoot the String representation of url to prepend to all the 896 files found. If an empty or null is sent it creates a 897 file:// url. 898 * @param dirToRead the String representation of the directory to read. 899 * @param recurse flags if the dir should be recursed 900 * @param the name of the file to save. 901 * @return the winamp playlist filename to save, 902 * (null to NOT save, empty string to use default) 903 **/ 904public static synchronized String createWinampList(String urlRoot, 905 String dirToRead, 906 boolean recurse, 907 String filename) 908{ 909 String retVal = ""; 910 String EOL = "\r\n"; 911 String winampHeader = "#EXTM3U" + EOL; 912 int winampHeaderLen = winampHeader.length(); 913 String winampFilename = "WinAmpList.m3u"; 914 boolean savingTheFile = true; 915 if (urlRoot == null) urlRoot = ""; 916 if (filename != null && 917 !filename.equals("")) 918 winampFilename = filename; 919 else if (filename == null) 920 savingTheFile = false; 921 File dirFileToRead = null; 922 923 if ( dirToRead !=null && 924 !dirToRead.equals("")) 925 { 926 dirFileToRead = new File(dirToRead); 927 928 //Check if dir is available 929 if(dirFileToRead.isDirectory() && dirFileToRead.canRead()) 930 { 931 // read files 932 retVal = ""; 933 String[] filesInDir = dirFileToRead.list(); 934 File tempFile; 935 String[] authorTitle = new String[2]; 936 937 // loop through all files 938 for (int i=0; i< filesInDir.length; i++) 939 { 940 tempFile = new File(dirToRead+File.separator+filesInDir[i]); 941 if(!tempFile.isDirectory()) 942 // files get added 943 { 944 if (filesInDir[i].trim().toLowerCase().endsWith(".mp3") || 945 filesInDir[i].trim().toLowerCase().endsWith(".ogg")) 946 { 947 authorTitle = parseAuthorAndTitleFromFilename(filesInDir[i].trim()); 948 retVal += "#EXTM3U:-1," + authorTitle[0] + " - " + 949 authorTitle[1] + EOL; 950 retVal += urlRoot + "/" + filesInDir[i] + EOL; 951 } 952 else 953 { 954 // ignore ... it's not a song file 955 } 956 } 957 else 958 // dirs get recursed 959 { 960 String recursedList = createWinampList(urlRoot+"/"+filesInDir[i], 961 tempFile.toString(), 962 recurse, 963 null); //never save the file on a recurse 964 if (recursedList != null && !recursedList.equals("")) 965 retVal += EOL + recursedList.substring(winampHeaderLen); 966 } 967 } 968 969 //clean up the retVal 970 retVal = retVal.trim(); 971 if (retVal != null && !retVal.equals("") && !retVal.startsWith(winampHeader)) 972 retVal = winampHeader + retVal; 973 974 975 // Save the file 976 if (savingTheFile) 977 { 978 try 979 { 980 if(filesInDir.length > 0 && retVal.length()>0) 981 { 982 FileWriter fileWriter = new FileWriter(dirToRead + File.separator + 983 winampFilename); 984 fileWriter.write(retVal,0,retVal.length()); 985 fileWriter.flush(); 986 fileWriter.close(); 987 } 988 else 989 { 990 // No Files return empty string 991 lastErrorMsg = "\n<P><B><I>Error Encountered:</I></B>"; 992 lastErrorMsg += "\n<P>NO files in " + dirToRead; 993 lastErrorMsg += "\n<HR>"; 994 retVal = ""; 995 } 996 } 997 catch (IOException ex) 998 { 999 lastErrorMsg = "\n<P><B><I>Error Encountered:</I></B>"; 1000 lastErrorMsg += "\n<P>Unable to create WinAmp Playlist file" + 1001 "for Directory ->\n" + dirToRead; 1002 lastErrorMsg += "\n<HR>"; 1003 } 1004 } 1005 } 1006 else 1007 { 1008 // error return empty string 1009 lastErrorMsg = "\n<P><B><I>Error Encountered:</I></B>"; 1010 lastErrorMsg += "\n<P>NOT a dir or Unable to initialize Directory for "+ 1011 "reading->" + dirString; 1012 lastErrorMsg += "\n<HR>"; 1013 retVal = ""; 1014 } 1015 } 1016 else 1017 { 1018 // error return empty string 1019 lastErrorMsg = "\n<P><B><I>Error Encountered:</I></B>"; 1020 lastErrorMsg += "\n<P>Unable to initialize Directory for reading->" + 1021 dirString; 1022 lastErrorMsg += "\n<HR>"; 1023 retVal = ""; 1024 } 1025 1026 return retVal; 1027} 1028 1029 1030/** 1031 * Reads the passed in directory and produces a winamp playlist for all 1032 * mp3 files in the dir.It returns an empty string "" if the file cannot be 1033 * created and fills the lastErrorMsg field. 1034 * 1035 * @param urlRoot the String representation of url to prepend to all the 1036 files found. If an empty or null is sent it creates a 1037 file:// url. 1038 * @param arg the String representation of the directory to read. 1039 * @param recurse flags if the dir should be recursed 1040 * @return the name of the winamp playlist file. 1041 **/ 1042public String createWinampList(String urlRoot, String arg, boolean recurse) 1043{ 1044 String retVal = "#EXTM3U\n"; 1045/* 1046 #EXTINF:239,Bryan Adams - Hey honey-I'm packin'you in! 1047 D:\tbg\stuff\mp3\BryanAdams_HeyHoney-ImPackinYouIn.mp3 1048*/ 1049 // parse the input parms to switch the dir we want 1050 1051 if (urlRoot == null) 1052 urlRoot = ""; 1053 1054 if(true )//initDir(arg, true)) 1055 { 1056 //autoFormatFileNames(); 1057 String[] files = dirFile.list(); 1058 fileName = dirFile.list(); 1059 File tempFile; 1060 String artistName = ""; 1061 String songTitle = ""; 1062 System.out.println("Creating Playlist with "+fileName.length+" Songs"); 1063 for (int i=0;i< fileName.length;i++) 1064 { 1065 tempFile = new File(dirString+File.separator+fileNamePath[i]+ 1066 fileName[i]); 1067 /*if(tempFile.isDirectory() && recurse) 1068 { 1069 retVal += createWinampList(urlRoot, 1070 dirString+File.separator+fileName[i], 1071 true); 1072 } 1073 else */ 1074 System.out.println("Filename="+tempFile.toString()); 1075 if (fileName[i].trim().toLowerCase().endsWith(".mp3") || 1076 fileName[i].trim().toLowerCase().endsWith(".ogg")) 1077 { 1078 retVal += "#EXTM3U:-1," + artistName + " - " + songTitle + "\n"; 1079 retVal += urlRoot + fileNamePath[i] + fileName[i] + "\n"; 1080 } 1081 } 1082 try 1083 { 1084 FileWriter fileWriter = new FileWriter(dirString + File.separator + 1085 winampFilename); 1086 fileWriter.write(retVal,0,retVal.length()); 1087 fileWriter.flush(); 1088 fileWriter.close(); 1089 } 1090 catch (IOException ex) 1091 { 1092 lastErrorMsg = "\n<P><B><I>Error Encountered:</I></B>"; 1093 lastErrorMsg += "\n<P>Unable to create WinAmp Playlist file for Directory ->" + dirString; 1094 lastErrorMsg += "\n<HR>"; 1095 } 1096 } 1097 else 1098 { 1099 lastErrorMsg = "\n<P><B><I>Error Encountered:</I></B>"; 1100 lastErrorMsg += "\n<P>Unable to initialize Directory for reading->" + dirString; 1101 lastErrorMsg += "\n<HR>"; 1102 } 1103 1104 1105 return(retVal); 1106} 1107 1108 1109/** For Testing Purposes **/ 1110public static void main (String [] args) 1111 { 1112 DirReadBean dirlist1 = new DirReadBean(); 1113 dirlist1.initFileIndex(); 1114 dirlist1.initFileName(); 1115 dirlist1.setDirString(""); 1116 String dir1 = "g:\\snd\\ogg\\"; 1117 dirlist1.initDir(dir1, "/ogg", true); // true to recurse 1118 String aList = dirlist1.getTitledAuthorList("ogg"); 1119 //System.out.println(aList); 1120 1121 String [] magNames = dirlist1.getArtistsNames(); 1122 String currName = ""; 1123 for (int i=0; i< magNames.length; i++) 1124 { 1125 currName = magNames[i]; 1126 System.out.println(currName); 1127 } 1128 1129 //dirlist1 = new DirReadBean(); 1130 //dirlist1.initFileIndex(); 1131 //dirlist1.initFileName(); 1132 //dirlist1.setDirString(""); 1133 String playlist = 1134 createWinampList("http://warp2/ogg", dir1, true,""); 1135 1136 if (!playlist.equals("")) 1137 System.out.println("Playlist written to file."); 1138 else 1139 System.out.println(getLastErrorMessage()); 1140 } 1141 1142 1143/* 1144Here is the revision log 1145------------------------ 1146$Log: DirReadBean.java,v $ 1147Revision 1.8 2002/05/02 22:32:45 tgutwin 1148Fixed Winamp list problems 1149Added recursive options 1150 1151Revision 1.7 2002/04/15 04:40:04 anonymous 1152 1153Added fields and methods to allow the getTitledAuthorList to ignore certain 1154files when parsing and preparing output. 1155 1156Revision 1.6 2002/03/27 20:08:18 anonymous 1157Trim the Artist Name Strings and added a A Name to each Artist Title 1158 1159Revision 1.5 2001/11/17 04:39:25 tgutwin 1160 1161Added a couple of get methods. 1162 1163Revision 1.4 2001/09/02 03:24:14 tgutwin 1164 1165Initial Rev of my custom DropDown Boxes. 1166 1167Revision 1.3 2001/08/08 23:36:21 tgutwin 1168 1169Added CVS Keywords. 1170 1171 1172*/ 1173} 1174 1175 1176