Source code: com/virtuosotechnologies/asaph/model/SongDatabase.java
1 /*
2 ================================================================================
3
4 FILE: SongDatabase.java
5
6 PROJECT:
7
8 Asaph
9
10 CONTENTS:
11
12 Toplevel interface for an Asaph model
13
14 PROGRAMMERS:
15
16 Daniel Azuma (DA) <dazuma@kagi.com>
17
18 COPYRIGHT:
19
20 Copyright (C) 2003 Daniel Azuma (dazuma@kagi.com)
21
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation; either version 2
25 of the License, or (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public
33 License along with this program; if not, write to
34 Free Software Foundation, Inc.
35 59 Temple Place, Suite 330
36 Boston, MA 02111-1307 USA
37
38 ================================================================================
39 */
40
41
42 package com.virtuosotechnologies.asaph.model;
43
44 import java.util.Set;
45 import java.util.Locale;
46 import javax.swing.event.UndoableEditListener;
47
48
49 /**
50 * This interface represents a database of songs. It provides facilities for
51 * simple searches by keyword and title, and allows clients to check out
52 * copies of songs, and check in changes.<p>
53 * This interface also specifies that all operations are atomic. That is,
54 * every mutation operation is atomic-- simultaneous mutations are serialized
55 * so they will not conflict. In addition, any query operation will always
56 * return information about a self-consistent state that the database was or
57 * could have been in at some point in the past. In-memory representations
58 * such as DOMImpl can implement this trivially by synchronizing each method,
59 * but an implementation with a SQL backend may require more work to
60 * implement these semantics.<p>
61 * Atomicity is not guaranteed for any of the other model interfaces.
62 */
63 public interface SongDatabase
64 {
65 //-------------------------------------------------------------------------
66 // Accessor methods
67 //-------------------------------------------------------------------------
68
69 /**
70 * Returns true if the database is writable. If this returns false, every mutation
71 * method will throw DatabaseNotWritableException. Note that even if this returns
72 * false, the database may still be changed by other entities. In other words,
73 * this method reflects the ability to write to the database through this interface,
74 * not necessarily through all interfaces.
75 *
76 * @return true if the database is writable, false if not.
77 */
78 public boolean isWritable();
79
80
81 /**
82 * Get a song by SongID. Note that the Song returned is a copy. Changes
83 * do not get reflected in the database until commitSong() succeeds.
84 * Returns null if the song doesn't exist in this database. (This could
85 * mean the song was deleted, or it is part of a different database.)
86 *
87 * @param id SongID
88 * @return the Song, or null if the id doesn't exist in this database.
89 * @exception SongDatabaseFailedException Catch-all exception for database-related
90 * problems. This will often have a cause exception, which may be exceptions
91 * like IOException or SQLException.
92 * @exception NullPointerException id was null
93 */
94 public Song checkOutSong(
95 SongID id)
96 throws
97 SongDatabaseFailedException;
98
99
100 /**
101 * Tests whether the given song id exists in this database. Returns
102 * false if the song was deleted or if it is part of a different database.
103 *
104 * @param id SongID to test
105 * @return true if the given SongID exists in this database.
106 * @exception SongDatabaseFailedException Catch-all exception for database-related
107 * problems. This will often have a cause exception, which may be exceptions
108 * like IOException or SQLException.
109 * @exception NullPointerException id was null
110 */
111 public boolean containsSongID(
112 SongID id)
113 throws
114 SongDatabaseFailedException;
115
116
117 /**
118 * Get the SongID for the given string, if it exists. This is used to
119 * deserialize a SongID that was stored persistently as its string
120 * representation. Returns null if the string does not correspond to a
121 * SongID that exists in this database.
122 *
123 * @param idStr serialized ID
124 * @return SongID
125 * @exception SongDatabaseFailedException Catch-all exception for database-related
126 * problems. This will often have a cause exception, which may be exceptions
127 * like IOException or SQLException.
128 */
129 public SongID getSongIDForString(
130 String idStr)
131 throws
132 SongDatabaseFailedException;
133
134
135 /**
136 * Create an empty result set.
137 *
138 * @return empty SongIDResultSet
139 */
140 public SongIDResultSet createEmptyResultSet();
141
142
143 /**
144 * Perform an operation on a set of songs. Operations could be accessors for
145 * information that could be cached by the database, such as the main title, or they
146 * could be filters applied to the result set, or they could have other semantics
147 * such as mass-checkouts or mass-checkins.
148 * The client specifies as the parameter a SongIDResultSet specifying the songs and
149 * parameter data for the operation. If null is passed, the database creates a new
150 * SongIDResultSet whose values are all the SongIDs in the database with null data
151 * for each one.
152 * The client also specifies the operation to perform.
153 * The method performs the operation on the result set in place, and then returns it.
154 * <p>
155 * Note that some SongDatabase implementations may choose to optimize this method
156 * by not calling the operation directly, but by analzying the semantics of the
157 * operation as declared by which operation semantics interfaces are implemented, and
158 * performing accelerated operations such as checking caches. Thus, do not expect that
159 * the SongOperation object you pass will actually be invoked.
160 * <p>
161 * One common use of this method is to get a result set containing all the SongIDs
162 * in the database. This is accomplished by passing null for the parameter, and
163 * a NopSemantics implementation for the operation.
164 *
165 * @param operation SongOperation to perform
166 * @param param input result set
167 * @return output result set
168 * @exception SongDatabaseFailedException Catch-all exception for database-related
169 * problems. This will often have a cause exception, which may be exceptions
170 * like IOException or SQLException.
171 */
172 public SongIDResultSet performOperation(
173 SongOperation operation,
174 SongIDResultSet param)
175 throws
176 SongDatabaseFailedException;
177
178
179 //-------------------------------------------------------------------------
180 // Mutation methods
181 //-------------------------------------------------------------------------
182
183 /**
184 * Add a new empty Song to the database.
185 *
186 * @param title main title of song to add
187 * @param locale Locale of song to add, or null to use the default locale
188 * @return ID of added Song
189 * @exception SongDatabaseFailedException Catch-all exception for database-related
190 * problems. This will often have a cause exception, which may be exceptions
191 * like IOException or SQLException.
192 * @exception NullPointerException title was null
193 */
194 public SongID addEmptySong(
195 String title,
196 Locale locale)
197 throws
198 SongDatabaseFailedException;
199
200
201 /**
202 * Makes a copy of the given song and adds it to the database. The given song need
203 * not be from this database.
204 * On completion, the song in the database will be identical to the given song,
205 * but the given song will not be modified. In particular, if the given song is
206 * owned by a different database, it will still be owned by that database.
207 *
208 * @return ID of added Song
209 * @exception SongDatabaseFailedException Catch-all exception for database-related
210 * problems. This will often have a cause exception, which may be exceptions
211 * like IOException or SQLException.
212 * @exception NullPointerException original was null
213 */
214 public SongID addCopyOfSong(
215 Song original)
216 throws
217 SongDatabaseFailedException;
218
219
220 /**
221 * Remove the given song from the database. Returns true if the song existed
222 * and was removed, or false if it was not present.
223 *
224 * @param id SongID of song to remove
225 * @return true if removed
226 * @exception SongDatabaseFailedException Catch-all exception for database-related
227 * problems. This will often have a cause exception, which may be exceptions
228 * like IOException or SQLException.
229 * @exception NullPointerException id was null
230 */
231 public boolean removeSong(
232 SongID id)
233 throws
234 SongDatabaseFailedException;
235
236
237 //-------------------------------------------------------------------------
238 // Commit-related methods
239 //-------------------------------------------------------------------------
240
241 /**
242 * Check the commit count to see if this song is still fresh. In other
243 * words, this returns true if the song has not been committed by someone
244 * else since this copy was checked out. Note that this should be taken to
245 * mean "this song was fresh a little while ago." A return value of true
246 * should not be taken as a guarantee that a subsequent call to commitSong
247 * will not throw SongNotFreshException, because another client may commit
248 * in between.
249 *
250 * @param song song to test
251 * @return true if the song is fresh.
252 * @exception SongDeletedException someone deleted this song in the meantime
253 * @exception SongDatabaseFailedException Catch-all exception for database-related
254 * problems. This will often have a cause exception, which may be exceptions
255 * like IOException or SQLException.
256 * @exception IllegalArgumentException this database is not the owner of the Song
257 * @exception NullPointerException song was null
258 */
259 public boolean isSongFresh(
260 Song song)
261 throws
262 SongDeletedException,
263 SongDatabaseFailedException;
264
265
266 /**
267 * Commit changes to this song. Also sets this song to fresh, since it now
268 * reflects the database contents. Does not perform the commit and throws
269 * SongNotFreshException if someone already committed a change in the meantime.
270 *
271 * @param song song to commit
272 * @exception SongNotFreshException someone committed a change in the meantime
273 * @exception SongDeletedException someone deleted this song in the meantime
274 * @exception SongDatabaseFailedException Catch-all exception for database-related
275 * problems. This will always have a cause exception, which may be exceptions
276 * like IOException or SQLException.
277 * @exception IllegalArgumentException this database is not the owner of the Song
278 * @exception NullPointerException song was null
279 */
280 public void commitSong(
281 Song song)
282 throws
283 SongNotFreshException,
284 SongDeletedException,
285 SongDatabaseFailedException;
286
287
288 /**
289 * Commit changes to this song. Also sets this song to fresh, since it now
290 * reflects the database contents. Commits and overwrites any changes made by
291 * clients in the meantime. (In other words, doesn't throw SongNotFreshException.)
292 *
293 * @param song song to commit
294 * @exception SongDeletedException someone deleted this song in the meantime
295 * @exception SongDatabaseFailedException Catch-all exception for database-related
296 * problems. This will always have a cause exception, which may be exceptions
297 * like IOException or SQLException.
298 * @exception IllegalArgumentException this database is not the owner of the Song
299 * @exception NullPointerException song was null
300 */
301 public void forceCommitSong(
302 Song song)
303 throws
304 SongDeletedException,
305 SongDatabaseFailedException;
306
307
308 /**
309 * Force-commit a song as the given SongID. The given SongID must be in this
310 * database, but the given checked-out song need not be from this database.
311 * On completion, the song in the database will be identical to the given song,
312 * but the given song will not be modified. In particular, if the given song is
313 * owned by a different database, it will still be owned by that database.
314 *
315 * @param song song to commit
316 * @param songID SongID to commit as
317 * @exception SongDeletedException someone deleted the SongID
318 * @exception SongDatabaseFailedException Catch-all exception for database-related
319 * problems. This will always have a cause exception, which may be exceptions
320 * like IOException or SQLException.
321 * @exception IllegalArgumentException this database is not the owner of the SongID
322 * @exception NullPointerException song or songID was null
323 */
324 public void forceCommitSongAs(
325 Song song,
326 SongID songID)
327 throws
328 SongDeletedException,
329 SongDatabaseFailedException;
330 }