View Javadoc

1   package org.musicontroller.service;
2   
3   import java.io.File;
4   
5   import org.musicontroller.core.MusicDirProvider;
6   import org.musicontroller.importer.ImporterException;
7   import org.musicontroller.importer.MusicArchiveEntryBean;
8   import org.varienaja.util.FileOperations;
9   
10  /**
11   * This class implements utilities for (MP3) file
12   * manipulation. This class knows about the conventions
13   * MusiController uses for the storage of its MP3 files.
14   * 
15   * @author drexler
16   * @version $Id: FileUtils.java,v 1.1 2010/03/16 18:55:42 varienaja Exp $
17   */
18  public class FileUtils implements MusicDirProvider {
19  
20  	/**
21  	 * This injected property defines what the baselocation of all files is.
22  	 * stored.
23  	 */
24  	private static String _basedir;
25  
26  	/**
27  	 * No arguments constructor.
28  	 */
29  	public FileUtils() {
30  		_basedir = null;
31  	}
32  	
33  	/**
34  	 * Creates a directory if it didn't exist
35  	 * @param dir The directory to create.
36  	 * @throws Exception, if the directory didn't exist and could not be created.
37  	 */
38  	private void createDir(String dir) throws Exception {
39  		File test = new File(dir);
40  		if (!test.exists()) {
41  			if (!test.mkdirs()) {
42  				throw new Exception("Could not create MusiController-directory: "+dir);
43  			}
44  		}
45  	}
46  	
47  	/**
48  	 * Setter for the music archive directory.
49  	 * @param basedir The base directory
50  	 */
51  	public void setBasedir(String basedir) throws Exception {
52  		_basedir = basedir;
53  		
54  		//Test existence of all directories, and try to create
55  		createDir(_basedir);
56  		createDir(getArchivedir());
57  		createDir(getMyAccountdir());
58  		createDir(getCoverdir());
59  		createDir(getReviewdir());
60  		createDir(getIndexdir());
61  		createDir(getUploaddir());
62  		createDir(getUnpackdir());
63  	}
64  	
65  	/**
66  	 * Getter for the music archive directory. Returns the set basedir
67  	 * with "/songs" appended. If the basedir is null then just returns
68  	 * "songs".
69  	 * 
70  	 * @return The music archive directory.
71  	 */
72  	public static String getArchivedir() {
73  		return _basedir==null ? "songs" : _basedir+File.separator+"songs";
74  	}
75  	
76  	/*
77  	 * (non-Javadoc)
78  	 * @see org.musicontroller.core.MusicDirProvider#getMusicDirectory()
79  	 */
80  	public String getMusicDirectory() {
81  		return getArchivedir();
82  	}
83  	
84  	/**
85  	 * Getter for the directory containing the myAccount settings.
86  	 * @return The directory containing the myaccount settings.
87  	 */
88  	public static String getMyAccountdir() {
89  		return _basedir+File.separator+"myAccount";
90  	}
91  	
92  	/**
93  	 * Getter for the directory containing the coverart.
94  	 * @return The directory containing the coverart.
95  	 */
96  	public static String getCoverdir() {
97  		return _basedir+File.separator+"covers";
98  	}
99  	
100 	/**
101 	 * Getter for the directory containing the reviews.
102 	 * @return The directory containing the reviews.
103 	 */
104 	public static String getReviewdir() {
105 		return _basedir+File.separator+"reviews";
106 	}
107 	
108 	/**
109 	 * Getter for the directory containing the lucene-index.
110 	 * @return The directory containing the lucene-index.
111 	 */
112 	public static String getIndexdir() {
113 		return _basedir+File.separator+"index";
114 	}
115 	
116 	public static String getUploaddir() {
117 		return _basedir+File.separator+"upload";
118 	}
119 
120 	/**
121 	 * Returns the location of the directory where uploaded music
122 	 * archives get unpacked. The returned name does not end in a
123 	 * file separator character.
124 	 * @return
125 	 */
126 	public static String getUnpackdir() {
127 		return _basedir+File.separator+"unpack";
128 	}
129 	
130 	/**
131 	 * Determine the storage hash (directory) name where this MP3 file
132 	 * will be written to. This method returns the first letter of the
133 	 * band name as the storage hash name. This is consistent with older
134 	 * versions of MusiController.
135 	 * @param song The music archive entry to find the storage hash name for.
136 	 * @return The name of the storage hash (directory) where the song should
137 	 *         be written to, or "_" if the song has a null or empty bandname.
138 	 */
139 	protected static String getStorageHashname(MusicArchiveEntryBean song) {
140 		if(song==null) {
141 			return "_";
142 		}
143 		String bandname = song.getBandName();
144 		if(bandname==null||bandname.length()<1) {
145 			return "_";
146 		}
147 		bandname = bandname.trim();
148 		if(bandname.isEmpty()) {
149 			throw new IllegalArgumentException("The songs band name contains no non whitespace characters.");
150 		}
151 		return FileOperations.translateIllegalFileChars(bandname).substring(0,1);
152 	}
153 
154 	/**
155 	 * Returns the location of the MP3 file of a new song.
156 	 * The location is splitted into three parts:
157 	 * <ol>
158 	 * <li>Songs-directory of MusiController</li>
159 	 * <li>Relative part of the filename for this song</li>
160 	 * <li>filename</li>
161 	 * </ol>
162 	 * @param song
163 	 * @return The location for the new Song. In order to use it, join them
164 	 * together with File.separator-characters.
165 	 * @throws ImporterException If the song is null.
166 	 */
167 	public static String[] getNewSongDestination(MusicArchiveEntryBean song) { 
168 		if (song==null) {
169 			throw new IllegalArgumentException("Song must not be null.");
170 		}
171 		if(song.getBandName()==null) {
172 			throw new IllegalArgumentException("Bandname must not be null.");
173 		}
174 		if(song.getSongName()==null) {
175 			throw new IllegalArgumentException("Songname must not be null.");
176 		}
177 		if(song.getBandName().trim().length()<1) {
178 			throw new IllegalArgumentException("Bandname must not be empty.");
179 		}
180 		if(song.getSongName().trim().length()<1) {
181 			throw new IllegalArgumentException("Songname must not be null.");
182 		}
183 		
184 		String[] result = new String[3];
185 		result[0] = getArchivedir();
186 		result[1] = getStorageHashname(song) + File.separator + FileOperations.translateIllegalFileChars(song.getBandName());
187 		String tmp = FileOperations.translateIllegalFileChars(song.getSongName());
188 		result[2] = generateUniqueFilename(result[0] + File.separator + result[1], tmp, ".mp3");
189 		
190 		return result;
191 	}
192 	
193 	/**
194 	 * Generates a unique filename. When a intended filename already exists, new
195 	 * names are generated with (1), (2), ... in the filename.
196 	 * @param path The path
197 	 * @param name The filename (without extension)
198 	 * @param extension The extension
199 	 * @return The name + extension (but not path) which is unique.
200 	 */
201 	private static String generateUniqueFilename(String path, String name, String extension) {
202 		String testname = name + extension;
203 		File testFile = new File(path + File.separator + testname);
204 		int counter=1;
205 		while(testFile.exists()) {
206 			testname = name + " (" + String.valueOf(counter) + ")" + extension;
207 			testFile = new File(path + File.separator + testname);
208 			counter++;
209 		}
210 		return testname;
211 	}
212 	
213 }