source: trunk/src/org/apollo/io/AudioPathManager.java@ 1006

Last change on this file since 1006 was 489, checked in by davidb, 11 years ago

Changes made when making Apollo run as an applet

File size: 6.4 KB
Line 
1package org.apollo.io;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileReader;
6import java.io.FileWriter;
7import java.io.IOException;
8import java.io.UnsupportedEncodingException;
9import java.util.Random;
10
11import org.apollo.audio.structure.AudioStructureModel;
12import org.apollo.util.ApolloSystemLog;
13import org.apollo.util.RegExpFileFilter;
14
15/**
16 * Generates audio paths.
17 *
18 * @author Brook Novak
19 *
20 */
21public class AudioPathManager {
22
23 private AudioPathManager() {
24 // util constructor
25 }
26
27 /** Suffixed with the native file separator */
28 public static String AUDIO_HOME_DIRECTORY = "audio" + File.separatorChar;
29
30 /** Stores all virtual names created by this repository. */
31 private static final String VIRTUAL_NAME_BASEFILE = ".vnames";
32
33 public static final int PREAMBLE_LENGTH = 6;
34
35 private static long counter = 0;
36
37 private static Random rand = new Random(System.currentTimeMillis());
38
39 /**
40 * Class initializer.
41 * Ensures that the home directory(ies) exist and preps the counter
42 */
43 static {
44
45 String expeditee_home = System.getProperty("expeditee.home");
46
47 if (expeditee_home != null) {
48 AUDIO_HOME_DIRECTORY = expeditee_home + File.separator + AUDIO_HOME_DIRECTORY;
49 }
50
51 // Ensure audio directory exists
52 File dir = new File(AUDIO_HOME_DIRECTORY);
53 if (!dir.exists()) {
54 if (!dir.mkdir()) {
55 ApolloSystemLog.println("Unable to create missing audio home directory");
56 }
57 }
58
59 // Load counter
60 loadCounter(dir);
61 }
62
63 /**
64 * Loads the counter
65 * @param dir The dir where the audio files live.
66 */
67 private static void loadCounter(File dir) {
68 String[] files = getAudioFileNames(dir);
69 if (files == null) { // Due to IO exception
70 ApolloSystemLog.printError("Failed to read audio directory");
71 return;
72 }
73 long count = 0;
74 if (files != null) {
75 for (String f : files) {
76
77 int start = -1, end = -1;
78 for (int i = 0; i < f.length(); i++) {
79 if (Character.isDigit(f.charAt(i)) && start == -1) {
80 start = i;
81 } else if (!Character.isDigit(f.charAt(i)) && start != -1) {
82 end = i;
83 break;
84 }
85 }
86
87 if (start >= 0 && end == -1) end = f.length();
88
89 if (start > 0 && end >= start) { // not start >= 0 since missing preable
90
91 String tmp = f.substring(start, end);
92 long l = Long.parseLong(tmp);
93 if (l >= count)
94 count = l + 1;
95 }
96 }
97 }
98
99 counter = count;
100 }
101
102 /**
103 * @param dir
104 * @return
105 * Null if an IO exception occurs
106 */
107 private static String[] getAudioFileNames(File dir) {
108 return dir.list(new RegExpFileFilter("^[A-Z]+\\d+.*$"));
109 }
110
111 /**
112 * @return
113 * The list of audio files in the audio home directory.
114 * Can be empty. Null if directory does not exist or failed to
115 * read list of files.
116 */
117 public static String[] getAudioFileNames() {
118 File audioDir = new File(AUDIO_HOME_DIRECTORY);
119 if (!audioDir.exists() || !audioDir.isDirectory()) return null;
120 return getAudioFileNames(audioDir);
121 }
122
123
124 /**
125 * @return The current counter.
126 */
127 public static long getCounter() {
128 return counter;
129 }
130
131 /**
132 * Generates a filename that is unique within the AUDIO_HOME_DIRECTORY.
133 *
134 * @param extension
135 * The extension of the filename to generate. Exclude period.
136 *
137 * @return
138 * A free unused filename with the given extension. Excludes directory.
139 * Even if the path return is not used, it will never be re-generated.
140 */
141 public static String generateLocateFileName(String extension) {
142
143 String filename = generateRandomFilenameBase() + "." + extension;
144
145 File f = new File(AUDIO_HOME_DIRECTORY + filename);
146
147 if (AudioStructureModel.getInstance().getTrackGraphInfo(filename, null) != null ||
148 f.exists()) { // recurse: until found a free path:
149 return generateLocateFileName(extension);
150 }
151
152 return filename;
153 }
154
155 private static String generateRandomFilenameBase() {
156
157 counter++;
158 if (counter < 0) counter = 0; // wraps positivey
159
160 // Generate random alpha preamble
161 byte[] bytes = new byte[PREAMBLE_LENGTH];
162 rand.nextBytes(bytes);
163
164
165 for (int i = 0; i < PREAMBLE_LENGTH; i++) {
166 if (bytes[i] < 0) bytes[i] *= -1;
167 int alphacap = (65 + (Math.abs(bytes[i]) % 26)); // A-Z in US ASCII encoding
168 bytes[i] = (byte) alphacap;
169
170 }
171
172 // Decode ASCII Byte array to javas UTF-16 encoding
173 String preamble = null;
174
175 try {
176 preamble = new String(bytes, "US-ASCII");
177 } catch (UnsupportedEncodingException e) {
178 e.printStackTrace();
179 preamble = "AUDIO";
180 }
181
182 // Build the filename string
183 return preamble + counter;
184
185 }
186
187
188
189 /**
190 * Lots of room for improvement here, ensures that a virtual filename is unique .. stores
191 * allocated virtual filenames on file.
192 *
193 * @return
194 * The new virtual filename.
195 */
196 public static String generateVirtualFilename() {
197
198 // Ensure that the name base file exists. Assumes the audio home directory exists.
199 File vnameBase = new File(AUDIO_HOME_DIRECTORY + VIRTUAL_NAME_BASEFILE);
200 if (!vnameBase.exists()) {
201 try {
202 vnameBase.createNewFile();
203 } catch (IOException e) {
204 e.printStackTrace();
205 }
206 }
207
208 String vname = null;
209
210 while (vname == null) {
211 vname = generateRandomFilenameBase() + ".vrt";
212 assert(vname != null);
213
214 BufferedReader in = null;
215 String line = null;
216
217 try {
218
219 // Open the vbase for reading
220 in = new BufferedReader(new FileReader(vnameBase));
221
222 // Read the sbase file and check all names
223 while ((line = in.readLine()) != null) {
224 line = line.trim();
225 if (line.equalsIgnoreCase(vname)) break;
226 }
227
228 } catch (Exception e) {
229 e.printStackTrace();
230 break; // just use the last generated filename...
231
232 // Clean up
233 } finally {
234 if (in != null) {
235 try {
236 in.close();
237 } catch (IOException e) {
238 e.printStackTrace();
239 }
240 }
241 }
242
243 // Check to see if name is infact unique
244 if (AudioStructureModel.getInstance().getLinkedTrackGraphInfo(vname, null) == null &&
245 (line == null || !line.equalsIgnoreCase(vname))) {
246 // If so, then enter new entry into the db.
247 FileWriter out = null;
248
249 try {
250 // Open the vbase for appending
251 out = new FileWriter(vnameBase, true);
252 out.write("\n" + vname);
253
254 } catch (IOException e) {
255 e.printStackTrace();
256
257 // Clean up
258 } finally {
259 if (out != null) {
260 try {
261 out.close();
262 } catch (IOException e) {
263 e.printStackTrace();
264 }
265 }
266 }
267
268 } else vname = null;
269 }
270
271 // Return the generated vname
272 return vname;
273
274 }
275}
Note: See TracBrowser for help on using the repository browser.