KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > content > Bitstream


1 /*
2  * Bitstream.java
3  *
4  * Version: $Revision: 1.22 $
5  *
6  * Date: $Date: 2006/05/26 14:16:20 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.content;
41
42 import java.io.IOException JavaDoc;
43 import java.io.InputStream JavaDoc;
44 import java.sql.SQLException JavaDoc;
45 import java.util.ArrayList JavaDoc;
46 import java.util.List JavaDoc;
47
48 import org.apache.log4j.Logger;
49 import org.dspace.authorize.AuthorizeException;
50 import org.dspace.authorize.AuthorizeManager;
51 import org.dspace.core.ConfigurationManager;
52 import org.dspace.core.Constants;
53 import org.dspace.core.Context;
54 import org.dspace.core.LogManager;
55 import org.dspace.storage.bitstore.BitstreamStorageManager;
56 import org.dspace.storage.rdbms.DatabaseManager;
57 import org.dspace.storage.rdbms.TableRow;
58 import org.dspace.storage.rdbms.TableRowIterator;
59
60 /**
61  * Class representing bitstreams stored in the DSpace system.
62  * <P>
63  * When modifying the bitstream metadata, changes are not reflected in the
64  * database until <code>update</code> is called. Note that you cannot alter
65  * the contents of a bitstream; you need to create a new bitstream.
66  *
67  * @author Robert Tansley
68  * @version $Revision: 1.22 $
69  */

70 public class Bitstream extends DSpaceObject
71 {
72     /** log4j logger */
73     private static Logger log = Logger.getLogger(Bitstream.class);
74
75     /** Our context */
76     private Context bContext;
77
78     /** The row in the table representing this bitstream */
79     private TableRow bRow;
80
81     /** The bitstream format corresponding to this bitstream */
82     private BitstreamFormat bitstreamFormat;
83
84     /**
85      * Private constructor for creating a Bitstream object based on the contents
86      * of a DB table row.
87      *
88      * @param context
89      * the context this object exists in
90      * @param row
91      * the corresponding row in the table
92      * @throws SQLException
93      */

94     Bitstream(Context context, TableRow row) throws SQLException JavaDoc
95     {
96         bContext = context;
97         bRow = row;
98
99         // Get the bitstream format
100
bitstreamFormat = BitstreamFormat.find(context, row
101                 .getIntColumn("bitstream_format_id"));
102
103         if (bitstreamFormat == null)
104         {
105             // No format: use "Unknown"
106
bitstreamFormat = BitstreamFormat.findUnknown(context);
107
108             // Panic if we can't find it
109
if (bitstreamFormat == null)
110             {
111                 throw new IllegalStateException JavaDoc("No Unknown bitsream format");
112             }
113         }
114
115         // Cache ourselves
116
context.cache(this, row.getIntColumn("bitstream_id"));
117     }
118
119     /**
120      * Get a bitstream from the database. The bitstream metadata is loaded into
121      * memory.
122      *
123      * @param context
124      * DSpace context object
125      * @param id
126      * ID of the bitstream
127      *
128      * @return the bitstream, or null if the ID is invalid.
129      * @throws SQLException
130      */

131     public static Bitstream find(Context context, int id) throws SQLException JavaDoc
132     {
133         // First check the cache
134
Bitstream fromCache = (Bitstream) context
135                 .fromCache(Bitstream.class, id);
136
137         if (fromCache != null)
138         {
139             return fromCache;
140         }
141
142         TableRow row = DatabaseManager.find(context, "bitstream", id);
143
144         if (row == null)
145         {
146             if (log.isDebugEnabled())
147             {
148                 log.debug(LogManager.getHeader(context, "find_bitstream",
149                         "not_found,bitstream_id=" + id));
150             }
151
152             return null;
153         }
154
155         // not null, return Bitstream
156
if (log.isDebugEnabled())
157         {
158             log.debug(LogManager.getHeader(context, "find_bitstream",
159                     "bitstream_id=" + id));
160         }
161
162         return new Bitstream(context, row);
163     }
164
165     /**
166      * Create a new bitstream, with a new ID. The checksum and file size are
167      * calculated. This method is not public, and does not check authorisation;
168      * other methods such as Bundle.createBitstream() will check authorisation.
169      * The newly created bitstream has the "unknown" format.
170      *
171      * @param context
172      * DSpace context object
173      * @param is
174      * the bits to put in the bitstream
175      *
176      * @return the newly created bitstream
177      * @throws IOException
178      * @throws SQLException
179      */

180     static Bitstream create(Context context, InputStream JavaDoc is)
181             throws IOException JavaDoc, SQLException JavaDoc
182     {
183         // Store the bits
184
int bitstreamID = BitstreamStorageManager.store(context, is);
185
186         log.info(LogManager.getHeader(context, "create_bitstream",
187                 "bitstream_id=" + bitstreamID));
188
189         // Set the format to "unknown"
190
Bitstream bitstream = find(context, bitstreamID);
191         bitstream.setFormat(null);
192
193         return bitstream;
194     }
195
196     /**
197      * Register a new bitstream, with a new ID. The checksum and file size
198      * are calculated. This method is not public, and does not check
199      * authorisation; other methods such as Bundle.createBitstream() will
200      * check authorisation. The newly created bitstream has the "unknown"
201      * format.
202      *
203      * @param context DSpace context object
204      * @param assetstore corresponds to an assetstore in dspace.cfg
205      * @param bitstreamPath the path and filename relative to the assetstore
206      * @return the newly registered bitstream
207      * @throws IOException
208      * @throws SQLException
209      */

210     static Bitstream register(Context context,
211             int assetstore, String JavaDoc bitstreamPath)
212             throws IOException JavaDoc, SQLException JavaDoc
213     {
214         // Store the bits
215
int bitstreamID = BitstreamStorageManager.register(
216                 context, assetstore, bitstreamPath);
217
218         log.info(LogManager.getHeader(context,
219             "create_bitstream",
220             "bitstream_id=" + bitstreamID));
221
222         // Set the format to "unknown"
223
Bitstream bitstream = find(context, bitstreamID);
224         bitstream.setFormat(null);
225
226         return bitstream;
227     }
228
229     /**
230      * Get the internal identifier of this bitstream
231      *
232      * @return the internal identifier
233      */

234     public int getID()
235     {
236         return bRow.getIntColumn("bitstream_id");
237     }
238
239     public String JavaDoc getHandle()
240     {
241         // No Handles for bitstreams
242
return null;
243     }
244
245     /**
246      * Get the sequence ID of this bitstream
247      *
248      * @return the sequence ID
249      */

250     public int getSequenceID()
251     {
252         return bRow.getIntColumn("sequence_id");
253     }
254
255     /**
256      * Set the sequence ID of this bitstream
257      *
258      * @param sid
259      * the ID
260      */

261     public void setSequenceID(int sid)
262     {
263         bRow.setColumn("sequence_id", sid);
264     }
265
266     /**
267      * Get the name of this bitstream - typically the filename, without any path
268      * information
269      *
270      * @return the name of the bitstream
271      */

272     public String JavaDoc getName()
273     {
274         return bRow.getStringColumn("name");
275     }
276
277     /**
278      * Set the name of the bitstream
279      *
280      * @param n
281      * the new name of the bitstream
282      */

283     public void setName(String JavaDoc n)
284     {
285         bRow.setColumn("name", n);
286     }
287
288     /**
289      * Get the source of this bitstream - typically the filename with path
290      * information (if originally provided) or the name of the tool that
291      * generated this bitstream
292      *
293      * @return the source of the bitstream
294      */

295     public String JavaDoc getSource()
296     {
297         return bRow.getStringColumn("source");
298     }
299
300     /**
301      * Set the source of the bitstream
302      *
303      * @param n
304      * the new source of the bitstream
305      */

306     public void setSource(String JavaDoc n)
307     {
308         bRow.setColumn("source", n);
309     }
310
311     /**
312      * Get the description of this bitstream - optional free text, typically
313      * provided by a user at submission time
314      *
315      * @return the description of the bitstream
316      */

317     public String JavaDoc getDescription()
318     {
319         return bRow.getStringColumn("description");
320     }
321
322     /**
323      * Set the description of the bitstream
324      *
325      * @param n
326      * the new description of the bitstream
327      */

328     public void setDescription(String JavaDoc n)
329     {
330         bRow.setColumn("description", n);
331     }
332
333     /**
334      * Get the checksum of the content of the bitstream, for integrity checking
335      *
336      * @return the checksum
337      */

338     public String JavaDoc getChecksum()
339     {
340         return bRow.getStringColumn("checksum");
341     }
342
343     /**
344      * Get the algorithm used to calculate the checksum
345      *
346      * @return the algorithm, e.g. "MD5"
347      */

348     public String JavaDoc getChecksumAlgorithm()
349     {
350         return bRow.getStringColumn("checksum_algorithm");
351     }
352
353     /**
354      * Get the size of the bitstream
355      *
356      * @return the size in bytes
357      */

358     public long getSize()
359     {
360         return bRow.getLongColumn("size_bytes");
361     }
362
363     /**
364      * Set the user's format description. This implies that the format of the
365      * bitstream is uncertain, and the format is set to "unknown."
366      *
367      * @param desc
368      * the user's description of the format
369      * @throws SQLException
370      */

371     public void setUserFormatDescription(String JavaDoc desc) throws SQLException JavaDoc
372     {
373         // FIXME: Would be better if this didn't throw an SQLException,
374
// but we need to find the unknown format!
375
setFormat(null);
376         bRow.setColumn("user_format_description", desc);
377     }
378
379     /**
380      * Get the user's format description. Returns null if the format is known by
381      * the system.
382      *
383      * @return the user's format description.
384      */

385     public String JavaDoc getUserFormatDescription()
386     {
387         return bRow.getStringColumn("user_format_description");
388     }
389
390     /**
391      * Get the description of the format - either the user's or the description
392      * of the format defined by the system.
393      *
394      * @return a description of the format.
395      */

396     public String JavaDoc getFormatDescription()
397     {
398         if (bitstreamFormat.getShortDescription().equals("Unknown"))
399         {
400             // Get user description if there is one
401
String JavaDoc desc = bRow.getStringColumn("user_format_description");
402
403             if (desc == null)
404             {
405                 return "Unknown";
406             }
407
408             return desc;
409         }
410
411         // not null or Unknown
412
return bitstreamFormat.getShortDescription();
413     }
414
415     /**
416      * Get the format of the bitstream
417      *
418      * @return the format of this bitstream
419      */

420     public BitstreamFormat getFormat()
421     {
422         return bitstreamFormat;
423     }
424
425     /**
426      * Set the format of the bitstream. If the user has supplied a type
427      * description, it is cleared. Passing in <code>null</code> sets the type
428      * of this bitstream to "unknown".
429      *
430      * @param f
431      * the format of this bitstream, or <code>null</code> for
432      * unknown
433      * @throws SQLException
434      */

435     public void setFormat(BitstreamFormat f) throws SQLException JavaDoc
436     {
437         // FIXME: Would be better if this didn't throw an SQLException,
438
// but we need to find the unknown format!
439
if (f == null)
440         {
441             // Use "Unknown" format
442
bitstreamFormat = BitstreamFormat.findUnknown(bContext);
443         }
444         else
445         {
446             bitstreamFormat = f;
447         }
448
449         // Remove user type description
450
bRow.setColumnNull("user_format_description");
451
452         // Update the ID in the table row
453
bRow.setColumn("bitstream_format_id", bitstreamFormat.getID());
454     }
455
456     /**
457      * Update the bitstream metadata. Note that the content of the bitstream
458      * cannot be changed - for that you need to create a new bitstream.
459      *
460      * @throws SQLException
461      * @throws AuthorizeException
462      */

463     public void update() throws SQLException JavaDoc, AuthorizeException
464     {
465         // Check authorisation
466
AuthorizeManager.authorizeAction(bContext, this, Constants.WRITE);
467
468         log.info(LogManager.getHeader(bContext, "update_bitstream",
469                 "bitstream_id=" + getID()));
470
471         DatabaseManager.update(bContext, bRow);
472     }
473
474     /**
475      * Delete the bitstream, including any mappings to bundles
476      *
477      * @throws SQLException
478      */

479     void delete() throws SQLException JavaDoc
480     {
481         // changed to a check on remove
482
// Check authorisation
483
//AuthorizeManager.authorizeAction(bContext, this, Constants.DELETE);
484
log.info(LogManager.getHeader(bContext, "delete_bitstream",
485                 "bitstream_id=" + getID()));
486
487         // Remove from cache
488
bContext.removeCached(this, getID());
489
490         // Remove policies
491
AuthorizeManager.removeAllPolicies(bContext, this);
492
493         // Remove bitstream itself
494
BitstreamStorageManager.delete(bContext, bRow
495                 .getIntColumn("bitstream_id"));
496     }
497
498     /**
499      * Retrieve the contents of the bitstream
500      *
501      * @return a stream from which the bitstream can be read.
502      * @throws IOException
503      * @throws SQLException
504      * @throws AuthorizeException
505      */

506     public InputStream JavaDoc retrieve() throws IOException JavaDoc, SQLException JavaDoc,
507             AuthorizeException
508     {
509         // Maybe should return AuthorizeException??
510
AuthorizeManager.authorizeAction(bContext, this, Constants.READ);
511
512         return BitstreamStorageManager.retrieve(bContext, bRow
513                 .getIntColumn("bitstream_id"));
514     }
515
516     /**
517      * Get the bundles this bitstream appears in
518      *
519      * @return array of <code>Bundle</code> s this bitstream appears in
520      * @throws SQLException
521      */

522     public Bundle[] getBundles() throws SQLException JavaDoc
523     {
524         // Get the bundle table rows
525
TableRowIterator tri = DatabaseManager.queryTable(bContext, "bundle",
526                 "SELECT bundle.* FROM bundle, bundle2bitstream WHERE " +
527                 "bundle.bundle_id=bundle2bitstream.bundle_id AND " +
528                 "bundle2bitstream.bitstream_id= ? ",
529                  bRow.getIntColumn("bitstream_id"));
530
531         // Build a list of Bundle objects
532
List JavaDoc bundles = new ArrayList JavaDoc();
533
534         while (tri.hasNext())
535         {
536             TableRow r = tri.next();
537
538             // First check the cache
539
Bundle fromCache = (Bundle) bContext.fromCache(Bundle.class, r
540                     .getIntColumn("bundle_id"));
541
542             if (fromCache != null)
543             {
544                 bundles.add(fromCache);
545             }
546             else
547             {
548                 bundles.add(new Bundle(bContext, r));
549             }
550         }
551
552         // close the TableRowIterator to free up resources
553
tri.close();
554
555         Bundle[] bundleArray = new Bundle[bundles.size()];
556         bundleArray = (Bundle[]) bundles.toArray(bundleArray);
557
558         return bundleArray;
559     }
560
561     /**
562      * return type found in Constants
563      *
564      * @return int Constants.BITSTREAM
565      */

566     public int getType()
567     {
568         return Constants.BITSTREAM;
569     }
570     
571     /**
572      * Determine if this bitstream is registered
573      *
574      * @return true if the bitstream is registered, false otherwise
575      */

576     public boolean isRegisteredBitstream() {
577         return BitstreamStorageManager
578                 .isRegisteredBitstream(bRow.getStringColumn("internal_id"));
579     }
580     
581     /**
582      * Get the asset store number where this bitstream is stored
583      *
584      * @return the asset store number of the bitstream
585      */

586     public int getStoreNumber() {
587         return bRow.getIntColumn("store_number");
588     }
589 }
590
Popular Tags