KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Collection.java
3  *
4  * Version: $Revision: 1.60 $
5  *
6  * Date: $Date: 2006/09/12 08:25:55 $
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.*;
45 import java.util.ArrayList JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.MissingResourceException JavaDoc;
48
49 import org.apache.log4j.Logger;
50 import org.dspace.authorize.AuthorizeException;
51 import org.dspace.authorize.AuthorizeManager;
52 import org.dspace.authorize.ResourcePolicy;
53 import org.dspace.core.ConfigurationManager;
54 import org.dspace.core.Constants;
55 import org.dspace.core.Context;
56 import org.dspace.core.I18N;
57 import org.dspace.core.LogManager;
58 import org.dspace.eperson.Group;
59 import org.dspace.handle.HandleManager;
60 import org.dspace.history.HistoryManager;
61 import org.dspace.search.DSIndexer;
62 import org.dspace.storage.rdbms.DatabaseManager;
63 import org.dspace.storage.rdbms.TableRow;
64 import org.dspace.storage.rdbms.TableRowIterator;
65 import org.dspace.workflow.WorkflowItem;
66
67 /**
68  * Class representing a collection.
69  * <P>
70  * The collection's metadata (name, introductory text etc), workflow groups, and
71  * default group of submitters are loaded into memory. Changes to metadata are
72  * not written to the database until <code>update</code> is called. If you
73  * create or remove a workflow group, the change is only reflected in the
74  * database after calling <code>update</code>. The default group of
75  * submitters is slightly different - creating or removing this has instant
76  * effect.
77  *
78  * @author Robert Tansley
79  * @version $Revision: 1.60 $
80  */

81 public class Collection extends DSpaceObject
82 {
83     /** log4j category */
84     private static Logger log = Logger.getLogger(Collection.class);
85
86     /** Our context */
87     private Context ourContext;
88
89     /** The table row corresponding to this item */
90     private TableRow collectionRow;
91
92     /** The logo bitstream */
93     private Bitstream logo;
94
95     /** The item template */
96     private Item template;
97
98     /** Our Handle */
99     private String JavaDoc handle;
100
101     /**
102      * Groups corresponding to workflow steps - NOTE these start from one, so
103      * workflowGroups[0] corresponds to workflow_step_1.
104      */

105     private Group[] workflowGroup;
106
107     /** The default group of submitters */
108     private Group submitters;
109
110     /** The default group of administrators */
111     private Group admins;
112
113     /**
114      * Construct a collection with the given table row
115      *
116      * @param context
117      * the context this object exists in
118      * @param row
119      * the corresponding row in the table
120      * @throws SQLException
121      */

122     Collection(Context context, TableRow row) throws SQLException
123     {
124         ourContext = context;
125         collectionRow = row;
126
127         // Get the logo bitstream
128
if (collectionRow.isColumnNull("logo_bitstream_id"))
129         {
130             logo = null;
131         }
132         else
133         {
134             logo = Bitstream.find(ourContext, collectionRow
135                     .getIntColumn("logo_bitstream_id"));
136         }
137
138         // Get the template item
139
if (collectionRow.isColumnNull("template_item_id"))
140         {
141             template = null;
142         }
143         else
144         {
145             template = Item.find(ourContext, collectionRow
146                     .getIntColumn("template_item_id"));
147         }
148
149         // Get the relevant groups
150
workflowGroup = new Group[3];
151
152         workflowGroup[0] = groupFromColumn("workflow_step_1");
153         workflowGroup[1] = groupFromColumn("workflow_step_2");
154         workflowGroup[2] = groupFromColumn("workflow_step_3");
155
156         submitters = groupFromColumn("submitter");
157         admins = groupFromColumn("admin");
158         
159         // Get our Handle if any
160
handle = HandleManager.findHandle(context, this);
161
162         // Cache ourselves
163
context.cache(this, row.getIntColumn("collection_id"));
164     }
165
166     /**
167      * Get a collection from the database. Loads in the metadata
168      *
169      * @param context
170      * DSpace context object
171      * @param id
172      * ID of the collection
173      *
174      * @return the collection, or null if the ID is invalid.
175      * @throws SQLException
176      */

177     public static Collection find(Context context, int id) throws SQLException
178     {
179         // First check the cache
180
Collection fromCache = (Collection) context.fromCache(Collection.class,
181                 id);
182
183         if (fromCache != null)
184         {
185             return fromCache;
186         }
187
188         TableRow row = DatabaseManager.find(context, "collection", id);
189
190         if (row == null)
191         {
192             if (log.isDebugEnabled())
193             {
194                 log.debug(LogManager.getHeader(context, "find_collection",
195                         "not_found,collection_id=" + id));
196             }
197
198             return null;
199         }
200
201         // not null, return Collection
202
if (log.isDebugEnabled())
203         {
204             log.debug(LogManager.getHeader(context, "find_collection",
205                     "collection_id=" + id));
206         }
207
208         return new Collection(context, row);
209     }
210
211     /**
212      * Create a new collection, with a new ID. This method is not public, and
213      * does not check authorisation.
214      *
215      * @param context
216      * DSpace context object
217      *
218      * @return the newly created collection
219      * @throws SQLException
220      * @throws AuthorizeException
221      */

222     static Collection create(Context context) throws SQLException,
223             AuthorizeException
224     {
225         TableRow row = DatabaseManager.create(context, "collection");
226         Collection c = new Collection(context, row);
227         c.handle = HandleManager.createHandle(context, c);
228
229         // create the default authorization policy for collections
230
// of 'anonymous' READ
231
Group anonymousGroup = Group.find(context, 0);
232
233         ResourcePolicy myPolicy = ResourcePolicy.create(context);
234         myPolicy.setResource(c);
235         myPolicy.setAction(Constants.READ);
236         myPolicy.setGroup(anonymousGroup);
237         myPolicy.update();
238
239         // now create the default policies for submitted items
240
myPolicy = ResourcePolicy.create(context);
241         myPolicy.setResource(c);
242         myPolicy.setAction(Constants.DEFAULT_ITEM_READ);
243         myPolicy.setGroup(anonymousGroup);
244         myPolicy.update();
245
246         myPolicy = ResourcePolicy.create(context);
247         myPolicy.setResource(c);
248         myPolicy.setAction(Constants.DEFAULT_BITSTREAM_READ);
249         myPolicy.setGroup(anonymousGroup);
250         myPolicy.update();
251
252         HistoryManager.saveHistory(context, c, HistoryManager.CREATE, context
253                 .getCurrentUser(), context.getExtraLogInfo());
254
255         log.info(LogManager.getHeader(context, "create_collection",
256                 "collection_id=" + row.getIntColumn("collection_id"))
257                 + ",handle=" + c.handle);
258
259         return c;
260     }
261
262     /**
263      * Get all collections in the system. These are alphabetically sorted by
264      * collection name.
265      *
266      * @param context
267      * DSpace context object
268      *
269      * @return the collections in the system
270      * @throws SQLException
271      */

272     public static Collection[] findAll(Context context) throws SQLException
273     {
274         TableRowIterator tri = DatabaseManager.queryTable(context, "collection",
275                 "SELECT * FROM collection ORDER BY name");
276
277         List JavaDoc collections = new ArrayList JavaDoc();
278
279         while (tri.hasNext())
280         {
281             TableRow row = tri.next();
282
283             // First check the cache
284
Collection fromCache = (Collection) context.fromCache(
285                     Collection.class, row.getIntColumn("collection_id"));
286
287             if (fromCache != null)
288             {
289                 collections.add(fromCache);
290             }
291             else
292             {
293                 collections.add(new Collection(context, row));
294             }
295         }
296         // close the TableRowIterator to free up resources
297
tri.close();
298
299         Collection[] collectionArray = new Collection[collections.size()];
300         collectionArray = (Collection[]) collections.toArray(collectionArray);
301
302         return collectionArray;
303     }
304
305     /**
306      * Get the in_archive items in this collection. The order is indeterminate.
307      *
308      * @return an iterator over the items in the collection.
309      * @throws SQLException
310      */

311     public ItemIterator getItems() throws SQLException
312     {
313         String JavaDoc myQuery = "SELECT item.* FROM item, collection2item WHERE "
314                 + "item.item_id=collection2item.item_id AND "
315                 + "collection2item.collection_id= ? "
316                 + "AND item.in_archive='1'";
317
318         TableRowIterator rows = DatabaseManager.queryTable(ourContext, "item",
319                 myQuery,getID());
320
321         return new ItemIterator(ourContext, rows);
322     }
323
324     /**
325      * Get all the items in this collection. The order is indeterminate.
326      *
327      * @return an iterator over the items in the collection.
328      * @throws SQLException
329      */

330     public ItemIterator getAllItems() throws SQLException
331     {
332         String JavaDoc myQuery = "SELECT item.* FROM item, collection2item WHERE "
333                 + "item.item_id=collection2item.item_id AND "
334                 + "collection2item.collection_id= ? ";
335
336         TableRowIterator rows = DatabaseManager.queryTable(ourContext, "item",
337                 myQuery,getID());
338
339         return new ItemIterator(ourContext, rows);
340     }
341
342      /**
343      * Get the internal ID of this collection
344      *
345      * @return the internal identifier
346      */

347     public int getID()
348     {
349         return collectionRow.getIntColumn("collection_id");
350     }
351
352     public String JavaDoc getHandle()
353     {
354         return handle;
355     }
356
357     /**
358      * Get the value of a metadata field
359      *
360      * @param field
361      * the name of the metadata field to get
362      *
363      * @return the value of the metadata field
364      *
365      * @exception IllegalArgumentException
366      * if the requested metadata field doesn't exist
367      */

368     public String JavaDoc getMetadata(String JavaDoc field)
369     {
370         return collectionRow.getStringColumn(field);
371     }
372
373     /**
374      * Set a metadata value
375      *
376      * @param field
377      * the name of the metadata field to get
378      * @param value
379      * value to set the field to
380      *
381      * @exception IllegalArgumentException
382      * if the requested metadata field doesn't exist
383      * @exception MissingResourceException
384      */

385     public void setMetadata(String JavaDoc field, String JavaDoc value) throws MissingResourceException JavaDoc
386     {
387         if ((field.trim()).equals("name") && (value.trim()).equals(""))
388         {
389             try
390             {
391                 value = I18N.message("untitled", Collection.class);
392             }
393             catch (MissingResourceException JavaDoc e)
394             {
395                 value = "Untitled";
396             }
397         }
398         collectionRow.setColumn(field, value);
399     }
400
401     /**
402      * Get the logo for the collection. <code>null</code> is return if the
403      * collection does not have a logo.
404      *
405      * @return the logo of the collection, or <code>null</code>
406      */

407     public Bitstream getLogo()
408     {
409         return logo;
410     }
411
412     /**
413      * Give the collection a logo. Passing in <code>null</code> removes any
414      * existing logo. You will need to set the format of the new logo bitstream
415      * before it will work, for example to "JPEG". Note that
416      * <code>update(/code> will need to be called for the change to take
417      * effect. Setting a logo and not calling <code>update</code> later may
418      * result in a previous logo lying around as an "orphaned" bitstream.
419      *
420      * @param is the stream to use as the new logo
421      *
422      * @return the new logo bitstream, or <code>null</code> if there is no
423      * logo (<code>null</code> was passed in)
424      * @throws AuthorizeException
425      * @throws IOException
426      * @throws SQLException
427      */

428     public Bitstream setLogo(InputStream JavaDoc is) throws AuthorizeException,
429             IOException JavaDoc, SQLException
430     {
431         // Check authorisation
432
// authorized to remove the logo when DELETE rights
433
// authorized when canEdit
434
if (!((is == null) && AuthorizeManager.authorizeActionBoolean(
435                 ourContext, this, Constants.DELETE)))
436         {
437             canEdit();
438         }
439
440         // First, delete any existing logo
441
if (!collectionRow.isColumnNull("logo_bitstream_id"))
442         {
443             logo.delete();
444         }
445
446         if (is == null)
447         {
448             collectionRow.setColumnNull("logo_bitstream_id");
449             logo = null;
450
451             log.info(LogManager.getHeader(ourContext, "remove_logo",
452                     "collection_id=" + getID()));
453         }
454         else
455         {
456             Bitstream newLogo = Bitstream.create(ourContext, is);
457             collectionRow.setColumn("logo_bitstream_id", newLogo.getID());
458             logo = newLogo;
459
460             // now create policy for logo bitstream
461
// to match our READ policy
462
List JavaDoc policies = AuthorizeManager.getPoliciesActionFilter(
463                     ourContext, this, Constants.READ);
464             AuthorizeManager.addPolicies(ourContext, policies, newLogo);
465
466             log.info(LogManager.getHeader(ourContext, "set_logo",
467                     "collection_id=" + getID() + "logo_bitstream_id="
468                             + newLogo.getID()));
469         }
470
471         return logo;
472     }
473
474     /**
475      * Create a workflow group for the given step if one does not already exist.
476      * Returns either the newly created group or the previously existing one.
477      * Note that while the new group is created in the database, the association
478      * between the group and the collection is not written until
479      * <code>update</code> is called.
480      *
481      * @param step
482      * the step (1-3) of the workflow to create or get the group for
483      *
484      * @return the workflow group associated with this collection
485      * @throws SQLException
486      * @throws AuthorizeException
487      */

488     public Group createWorkflowGroup(int step) throws SQLException,
489             AuthorizeException
490     {
491         // Check authorisation
492
AuthorizeManager.authorizeAction(ourContext, this, Constants.WRITE);
493
494         if (workflowGroup[step - 1] == null)
495         {
496             Group g = Group.create(ourContext);
497             g.setName("COLLECTION_" + getID() + "_WORKFLOW_STEP_" + step);
498             g.update();
499             setWorkflowGroup(step, g);
500
501             AuthorizeManager.addPolicy(ourContext, this, Constants.ADD, g);
502         }
503
504         return workflowGroup[step - 1];
505     }
506
507     /**
508      * Set the workflow group corresponding to a particular workflow step.
509      * <code>null</code> can be passed in if there should be no associated
510      * group for that workflow step; any existing group is NOT deleted.
511      *
512      * @param step
513      * the workflow step (1-3)
514      * @param g
515      * the new workflow group, or <code>null</code>
516      */

517     public void setWorkflowGroup(int step, Group g)
518     {
519         workflowGroup[step - 1] = g;
520
521         if (g == null)
522         {
523             collectionRow.setColumnNull("workflow_step_" + step);
524         }
525         else
526         {
527             collectionRow.setColumn("workflow_step_" + step, g.getID());
528         }
529     }
530
531     /**
532      * Get the the workflow group corresponding to a particular workflow step.
533      * This returns <code>null</code> if there is no group associated with
534      * this collection for the given step.
535      *
536      * @param step
537      * the workflow step (1-3)
538      *
539      * @return the group of reviewers or <code>null</code>
540      */

541     public Group getWorkflowGroup(int step)
542     {
543         return workflowGroup[step - 1];
544     }
545
546     /**
547      * Create a default submitters group if one does not already exist. Returns
548      * either the newly created group or the previously existing one. Note that
549      * other groups may also be allowed to submit to this collection by the
550      * authorization system.
551      *
552      * @return the default group of submitters associated with this collection
553      * @throws SQLException
554      * @throws AuthorizeException
555      */

556     public Group createSubmitters() throws SQLException, AuthorizeException
557     {
558         // Check authorisation
559
AuthorizeManager.authorizeAction(ourContext, this, Constants.WRITE);
560
561         if (submitters == null)
562         {
563             submitters = Group.create(ourContext);
564             submitters.setName("COLLECTION_" + getID() + "_SUBMIT");
565             submitters.update();
566         }
567
568         // register this as the submitter group
569
collectionRow.setColumn("submitter", submitters.getID());
570         
571         AuthorizeManager.addPolicy(ourContext, this, Constants.ADD, submitters);
572
573         return submitters;
574     }
575
576     /**
577      * Get the default group of submitters, if there is one. Note that the
578      * authorization system may allow others to submit to the collection, so
579      * this is not necessarily a definitive list of potential submitters.
580      * <P>
581      * The default group of submitters for collection 100 is the one called
582      * <code>collection_100_submit</code>.
583      *
584      * @return the default group of submitters, or <code>null</code> if there
585      * is no default group.
586      */

587     public Group getSubmitters()
588     {
589         return submitters;
590     }
591
592     /**
593      * Create a default administrators group if one does not already exist.
594      * Returns either the newly created group or the previously existing one.
595      * Note that other groups may also be administrators.
596      *
597      * @return the default group of editors associated with this collection
598      * @throws SQLException
599      * @throws AuthorizeException
600      */

601     public Group createAdministrators() throws SQLException, AuthorizeException
602     {
603         // Check authorisation
604
AuthorizeManager.authorizeAction(ourContext, this, Constants.WRITE);
605
606         if (admins == null)
607         {
608             admins = Group.create(ourContext);
609             admins.setName("COLLECTION_" + getID() + "_ADMIN");
610             admins.update();
611         }
612
613         AuthorizeManager.addPolicy(ourContext, this,
614                 Constants.COLLECTION_ADMIN, admins);
615
616         // register this as the admin group
617
collectionRow.setColumn("admin", admins.getID());
618         
619         // administrators also get ADD on the submitter group
620
if (submitters != null)
621         {
622             AuthorizeManager.addPolicy(ourContext, submitters, Constants.ADD,
623                     admins);
624         }
625
626         return admins;
627     }
628
629     /**
630      * Get the default group of administrators, if there is one. Note that the
631      * authorization system may allow others to be administrators for the
632      * collection.
633      * <P>
634      * The default group of administrators for collection 100 is the one called
635      * <code>collection_100_admin</code>.
636      *
637      * @return group of administrators, or <code>null</code> if there is no
638      * default group.
639      */

640     public Group getAdministrators()
641     {
642         return admins;
643     }
644
645     /**
646      * Get the license that users must grant before submitting to this
647      * collection. If the collection does not have a specific license, the
648      * site-wide default is returned.
649      *
650      * @return the license for this collection
651      */

652     public String JavaDoc getLicense()
653     {
654         String JavaDoc license = collectionRow.getStringColumn("license");
655
656         if ((license == null) || license.equals(""))
657         {
658             // Fallback to site-wide default
659
license = ConfigurationManager.getDefaultSubmissionLicense();
660         }
661
662         return license;
663     }
664
665     /**
666      * Find out if the collection has a custom license
667      *
668      * @return <code>true</code> if the collection has a custom license
669      */

670     public boolean hasCustomLicense()
671     {
672         String JavaDoc license = collectionRow.getStringColumn("license");
673
674         return ((license != null) && !license.equals(""));
675     }
676
677     /**
678      * Set the license for this collection. Passing in <code>null</code> means
679      * that the site-wide default will be used.
680      *
681      * @param license
682      * the license, or <code>null</code>
683      */

684     public void setLicense(String JavaDoc license)
685     {
686         if (license == null)
687         {
688             collectionRow.setColumnNull("license");
689         }
690         else
691         {
692             collectionRow.setColumn("license", license);
693         }
694     }
695
696     /**
697      * Get the template item for this collection. <code>null</code> is
698      * returned if the collection does not have a template. Submission
699      * mechanisms may copy this template to provide a convenient starting point
700      * for a submission.
701      *
702      * @return the item template, or <code>null</code>
703      */

704     public Item getTemplateItem() throws SQLException
705     {
706         return template;
707     }
708
709     /**
710      * Create an empty template item for this collection. If one already exists,
711      * no action is taken. Caution: Make sure you call <code>update</code> on
712      * the collection after doing this, or the item will have been created but
713      * the collection record will not refer to it.
714      *
715      * @throws SQLException
716      * @throws AuthorizeException
717      */

718     public void createTemplateItem() throws SQLException, AuthorizeException
719     {
720         // Check authorisation
721
canEdit();
722
723         if (template == null)
724         {
725             template = Item.create(ourContext);
726             collectionRow.setColumn("template_item_id", template.getID());
727
728             log.info(LogManager.getHeader(ourContext, "create_template_item",
729                     "collection_id=" + getID() + ",template_item_id="
730                             + template.getID()));
731         }
732     }
733
734     /**
735      * Remove the template item for this collection, if there is one. Note that
736      * since this has to remove the old template item ID from the collection
737      * record in the database, the colletion record will be changed, including
738      * any other changes made; in other words, this method does an
739      * <code>update</code>.
740      *
741      * @throws SQLException
742      * @throws AuthorizeException
743      * @throws IOException
744      */

745     public void removeTemplateItem() throws SQLException, AuthorizeException,
746             IOException JavaDoc
747     {
748         // Check authorisation
749
canEdit();
750
751         collectionRow.setColumnNull("template_item_id");
752         DatabaseManager.update(ourContext, collectionRow);
753
754         if (template != null)
755         {
756             log.info(LogManager.getHeader(ourContext, "remove_template_item",
757                     "collection_id=" + getID() + ",template_item_id="
758                             + template.getID()));
759
760             template.delete();
761             template = null;
762         }
763     }
764
765     /**
766      * Add an item to the collection. This simply adds a relationship between
767      * the item and the collection - it does nothing like set an issue date,
768      * remove a personal workspace item etc. This has instant effect;
769      * <code>update</code> need not be called.
770      *
771      * @param item
772      * item to add
773      * @throws SQLException
774      * @throws AuthorizeException
775      */

776     public void addItem(Item item) throws SQLException, AuthorizeException
777     {
778         // Check authorisation
779
AuthorizeManager.authorizeAction(ourContext, this, Constants.ADD);
780
781         log.info(LogManager.getHeader(ourContext, "add_item", "collection_id="
782                 + getID() + ",item_id=" + item.getID()));
783
784         // Create mapping
785
TableRow row = DatabaseManager.create(ourContext, "collection2item");
786
787         row.setColumn("collection_id", getID());
788         row.setColumn("item_id", item.getID());
789
790         DatabaseManager.update(ourContext, row);
791     }
792
793     /**
794      * Remove an item. If the item is then orphaned, it is deleted.
795      *
796      * @param item
797      * item to remove
798      * @throws SQLException
799      * @throws AuthorizeException
800      * @throws IOException
801      */

802     public void removeItem(Item item) throws SQLException, AuthorizeException,
803             IOException JavaDoc
804     {
805         // Check authorisation
806
AuthorizeManager.authorizeAction(ourContext, this, Constants.REMOVE);
807
808         log.info(LogManager.getHeader(ourContext, "remove_item",
809                 "collection_id=" + getID() + ",item_id=" + item.getID()));
810
811         DatabaseManager.updateQuery(ourContext,
812                 "DELETE FROM collection2item WHERE collection_id= ? "+
813                 "AND item_id= ? ",
814                 getID(), item.getID());
815
816         // Is the item an orphan?
817
TableRowIterator tri = DatabaseManager.query(ourContext,
818                 "SELECT * FROM collection2item WHERE item_id= ? ",
819                 item.getID());
820
821         if (!tri.hasNext())
822         {
823             //make the right to remove the item explicit because the implicit
824
// relation
825
//has been removed. This only has to concern the currentUser
826
// because
827
//he started the removal process and he will end it too.
828
//also add right to remove from the item to remove it's bundles.
829
AuthorizeManager.addPolicy(ourContext, item, Constants.DELETE,
830                     ourContext.getCurrentUser());
831             AuthorizeManager.addPolicy(ourContext, item, Constants.REMOVE,
832                     ourContext.getCurrentUser());
833
834             // Orphan; delete it
835
item.delete();
836         }
837         // close the TableRowIterator to free up resources
838
tri.close();
839     }
840
841     /**
842      * Update the collection metadata (including logo, and workflow groups) to
843      * the database. Inserts if this is a new collection.
844      *
845      * @throws SQLException
846      * @throws IOException
847      * @throws AuthorizeException
848      */

849     public void update() throws SQLException, IOException JavaDoc, AuthorizeException
850     {
851         // Check authorisation
852
canEdit();
853
854         HistoryManager.saveHistory(ourContext, this, HistoryManager.MODIFY,
855                 ourContext.getCurrentUser(), ourContext.getExtraLogInfo());
856
857         log.info(LogManager.getHeader(ourContext, "update_collection",
858                 "collection_id=" + getID()));
859
860         DatabaseManager.update(ourContext, collectionRow);
861
862         // reindex this collection (could be smarter, to only do when name
863
// changes)
864
DSIndexer.reIndexContent(ourContext, this);
865     }
866
867     public boolean canEditBoolean() throws java.sql.SQLException JavaDoc
868     {
869         try
870         {
871             canEdit();
872
873             return true;
874         }
875         catch (AuthorizeException e)
876         {
877             return false;
878         }
879     }
880
881     public void canEdit() throws AuthorizeException, SQLException
882     {
883         Community[] parents = getCommunities();
884
885         for (int i = 0; i < parents.length; i++)
886         {
887             if (AuthorizeManager.authorizeActionBoolean(ourContext, parents[i],
888                     Constants.WRITE))
889             {
890                 return;
891             }
892
893             if (AuthorizeManager.authorizeActionBoolean(ourContext, parents[i],
894                     Constants.ADD))
895             {
896                 return;
897             }
898         }
899
900         AuthorizeManager.authorizeAnyOf(ourContext, this, new int[] {
901                 Constants.WRITE, Constants.COLLECTION_ADMIN });
902     }
903
904     /**
905      * Delete the collection, including the metadata and logo. Items that are
906      * then orphans are deleted. Groups associated with this collection
907      * (workflow participants and submitters) are NOT deleted.
908      *
909      * @throws SQLException
910      * @throws AuthorizeException
911      * @throws IOException
912      */

913     void delete() throws SQLException, AuthorizeException, IOException JavaDoc
914     {
915         log.info(LogManager.getHeader(ourContext, "delete_collection",
916                 "collection_id=" + getID()));
917
918         // remove from index
919
DSIndexer.unIndexContent(ourContext, this);
920
921         // Remove from cache
922
ourContext.removeCached(this, getID());
923
924         HistoryManager.saveHistory(ourContext, this, HistoryManager.REMOVE,
925                 ourContext.getCurrentUser(), ourContext.getExtraLogInfo());
926
927         // remove subscriptions - hmm, should this be in Subscription.java?
928
DatabaseManager.updateQuery(ourContext,
929                 "DELETE FROM subscription WHERE collection_id= ? ",
930                 getID());
931
932         // Remove Template Item
933
removeTemplateItem();
934         
935         // Remove items
936
ItemIterator items = getAllItems();
937
938         while (items.hasNext())
939         {
940             Item item = items.next();
941             
942             if (item.isOwningCollection(this))
943             {
944             // the collection to be deletd is the owning collection, thus remove
945
// the item from all collections it belongs to
946
Collection[] collections = item.getCollections();
947                 for (int i=0; i< collections.length; i++)
948                 {
949                     collections[i].removeItem(item);
950                 }
951                     
952             }
953             // the item was only mapped to this collection, so just remove it
954
else
955             {
956                 removeItem(item);
957             }
958         }
959
960         // Delete bitstream logo
961
setLogo(null);
962
963         // Remove all authorization policies
964
AuthorizeManager.removeAllPolicies(ourContext, this);
965
966         // Remove any WorkflowItems
967
WorkflowItem[] wfarray = WorkflowItem
968                 .findByCollection(ourContext, this);
969
970         for (int x = 0; x < wfarray.length; x++)
971         {
972             // remove the workflowitem first, then the item
973
Item myItem = wfarray[x].getItem();
974             wfarray[x].deleteWrapper();
975             myItem.delete();
976         }
977
978         // Remove any WorkspaceItems
979
WorkspaceItem[] wsarray = WorkspaceItem.findByCollection(ourContext,
980                 this);
981
982         for (int x = 0; x < wsarray.length; x++)
983         {
984             wsarray[x].deleteAll();
985         }
986
987         // Delete collection row
988
DatabaseManager.delete(ourContext, collectionRow);
989
990         // Remove any workflow groups - must happen after deleting collection
991
Group g = null;
992
993         g = getWorkflowGroup(1);
994
995         if (g != null)
996         {
997             g.delete();
998         }
999
1000        g = getWorkflowGroup(2);
1001
1002        if (g != null)
1003        {
1004            g.delete();
1005        }
1006
1007        g = getWorkflowGroup(3);
1008
1009        if (g != null)
1010        {
1011            g.delete();
1012        }
1013
1014        // Remove default administrators group
1015
g = getAdministrators();
1016
1017        if (g != null)
1018        {
1019            g.delete();
1020        }
1021
1022        // Remove default submitters group
1023
g = getSubmitters();
1024
1025        if (g != null)
1026        {
1027            g.delete();
1028        }
1029    }
1030
1031    /**
1032     * Get the communities this collection appears in
1033     *
1034     * @return array of <code>Community</code> objects
1035     * @throws SQLException
1036     */

1037    public Community[] getCommunities() throws SQLException
1038    {
1039        // Get the bundle table rows
1040
TableRowIterator tri = DatabaseManager.queryTable(ourContext,"community",
1041                        "SELECT community.* FROM community, community2collection WHERE " +
1042                        "community.community_id=community2collection.community_id " +
1043                        "AND community2collection.collection_id= ? ",
1044                        getID());
1045
1046        // Build a list of Community objects
1047
List JavaDoc communities = new ArrayList JavaDoc();
1048
1049        while (tri.hasNext())
1050        {
1051            TableRow row = tri.next();
1052
1053            // First check the cache
1054
Community owner = (Community) ourContext.fromCache(Community.class,
1055                    row.getIntColumn("community_id"));
1056
1057            if (owner == null)
1058            {
1059                owner = new Community(ourContext, row);
1060            }
1061
1062            communities.add(owner);
1063
1064            // now add any parent communities
1065
Community[] parents = owner.getAllParents();
1066
1067            for (int i = 0; i < parents.length; i++)
1068            {
1069                communities.add(parents[i]);
1070            }
1071        }
1072        // close the TableRowIterator to free up resources
1073
tri.close();
1074
1075        Community[] communityArray = new Community[communities.size()];
1076        communityArray = (Community[]) communities.toArray(communityArray);
1077
1078        return communityArray;
1079    }
1080
1081    /**
1082     * Return <code>true</code> if <code>other</code> is the same Collection
1083     * as this object, <code>false</code> otherwise
1084     *
1085     * @param other
1086     * object to compare to
1087     *
1088     * @return <code>true</code> if object passed in represents the same
1089     * collection as this object
1090     */

1091    public boolean equals(Object JavaDoc other)
1092    {
1093        if (!(other instanceof Collection))
1094        {
1095            return false;
1096        }
1097
1098        return (getID() == ((Collection) other).getID());
1099    }
1100
1101    /**
1102     * Utility method for reading in a group from a group ID in a column. If the
1103     * column is null, null is returned.
1104     *
1105     * @param col
1106     * the column name to read
1107     * @return the group referred to by that column, or null
1108     * @throws SQLException
1109     */

1110    private Group groupFromColumn(String JavaDoc col) throws SQLException
1111    {
1112        if (collectionRow.isColumnNull(col))
1113        {
1114            return null;
1115        }
1116
1117        return Group.find(ourContext, collectionRow.getIntColumn(col));
1118    }
1119
1120    /**
1121     * return type found in Constants
1122     *
1123     * @return int Constants.COLLECTION
1124     */

1125    public int getType()
1126    {
1127        return Constants.COLLECTION;
1128    }
1129
1130    /**
1131     * return an array of collections that user has a given permission on
1132     * (useful for trimming 'select to collection' list) or figuring out which
1133     * collections a person is an editor for.
1134     *
1135     * @param context
1136     * @param comm
1137     * (optional) restrict search to a community, else null
1138     * @param actionID
1139     * fo the action
1140     *
1141     * @return Collection [] of collections with matching permissions
1142     * @throws SQLException
1143     */

1144    public static Collection[] findAuthorized(Context context, Community comm,
1145            int actionID) throws java.sql.SQLException JavaDoc
1146    {
1147        List JavaDoc myResults = new ArrayList JavaDoc();
1148
1149        Collection[] myCollections = null;
1150
1151        if (comm != null)
1152        {
1153            myCollections = comm.getCollections();
1154        }
1155        else
1156        {
1157            myCollections = Collection.findAll(context);
1158        }
1159
1160        // now build a list of collections you have authorization for
1161
for (int i = 0; i < myCollections.length; i++)
1162        {
1163            if (AuthorizeManager.authorizeActionBoolean(context,
1164                    myCollections[i], actionID))
1165            {
1166                myResults.add(myCollections[i]);
1167            }
1168        }
1169
1170        myCollections = new Collection[myResults.size()];
1171        myCollections = (Collection[]) myResults.toArray(myCollections);
1172
1173        return myCollections;
1174    }
1175
1176    /**
1177     * counts items in this collection
1178     *
1179     * @return total items
1180     */

1181     public int countItems()
1182        throws SQLException
1183     {
1184        String JavaDoc query = "SELECT count(*) FROM collection2item, item WHERE "
1185            + "collection2item.collection_id = ? "
1186            + "AND collection2item.item_id = item.item_id "
1187            + "AND in_archive ='1' AND item.withdrawn='0' ";
1188
1189        PreparedStatement statement = ourContext.getDBConnection().prepareStatement(query);
1190        statement.setInt(1,getID());
1191        
1192        ResultSet rs = statement.executeQuery();
1193        
1194        rs.next();
1195        int itemcount = rs.getInt(1);
1196
1197        statement.close();
1198
1199        return itemcount;
1200     }
1201}
1202
Popular Tags