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

Last change on this file since 1303 was 1303, checked in by bln4, 5 years ago

Moved the static field USER_NOBODY to AuthenticatorBrowser from Browser as it makes more sense there.
Added functionality to log out, equiv to closing Expeditee and starting it again.

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