KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > app > webui > servlet > admin > EditItemServlet


1 /*
2  * EditItemServlet.java
3  *
4  * Version: $Revision: 1.22 $
5  *
6  * Date: $Date: 2006/10/25 11:22:10 $
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.app.webui.servlet.admin;
41
42 import java.io.BufferedInputStream JavaDoc;
43 import java.io.File JavaDoc;
44 import java.io.FileInputStream JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.io.InputStream JavaDoc;
47 import java.sql.SQLException JavaDoc;
48 import java.util.Collections JavaDoc;
49 import java.util.Enumeration JavaDoc;
50 import java.util.HashMap JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.LinkedList JavaDoc;
53 import java.util.List JavaDoc;
54 import java.util.StringTokenizer JavaDoc;
55
56 import javax.servlet.ServletException JavaDoc;
57 import javax.servlet.http.HttpServletRequest JavaDoc;
58 import javax.servlet.http.HttpServletResponse JavaDoc;
59
60 import org.apache.log4j.Logger;
61 import org.dspace.app.webui.servlet.DSpaceServlet;
62 import org.dspace.app.webui.util.FileUploadRequest;
63 import org.dspace.app.webui.util.JSPManager;
64 import org.dspace.app.webui.util.UIUtil;
65 import org.dspace.authorize.AuthorizeException;
66 import org.dspace.authorize.AuthorizeManager;
67 import org.dspace.content.Bitstream;
68 import org.dspace.content.BitstreamFormat;
69 import org.dspace.content.Bundle;
70 import org.dspace.content.Collection;
71 import org.dspace.content.DSpaceObject;
72 import org.dspace.content.FormatIdentifier;
73 import org.dspace.content.Item;
74 import org.dspace.content.MetadataField;
75 import org.dspace.content.MetadataSchema;
76 import org.dspace.core.Constants;
77 import org.dspace.core.Context;
78 import org.dspace.core.LogManager;
79 import org.dspace.handle.HandleManager;
80 import org.dspace.search.DSIndexer;
81 import org.dspace.license.CreativeCommons;
82
83 /**
84  * Servlet for editing and deleting (expunging) items
85  *
86  * @author Robert Tansley
87  * @version $Revision: 1.22 $
88  */

89 public class EditItemServlet extends DSpaceServlet
90 {
91     /** User wants to delete (expunge) an item */
92     public static final int START_DELETE = 1;
93
94     /** User confirms delete (expunge) of item */
95     public static final int CONFIRM_DELETE = 2;
96
97     /** User updates item */
98     public static final int UPDATE_ITEM = 3;
99
100     /** User starts withdrawal of item */
101     public static final int START_WITHDRAW = 4;
102
103     /** User confirms withdrawal of item */
104     public static final int CONFIRM_WITHDRAW = 5;
105
106     /** User reinstates a withdrawn item */
107     public static final int REINSTATE = 6;
108
109     /** Logger */
110     private static Logger log = Logger.getLogger(EditCommunitiesServlet.class);
111
112     protected void doDSGet(Context context, HttpServletRequest JavaDoc request,
113             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
114             SQLException JavaDoc, AuthorizeException
115     {
116         /*
117          * GET with no parameters displays "find by handle/id" form parameter
118          * item_id -> find and edit item with internal ID item_id parameter
119          * handle -> find and edit corresponding item if internal ID or Handle
120          * are invalid, "find by handle/id" form is displayed again with error
121          * message
122          */

123         int internalID = UIUtil.getIntParameter(request, "item_id");
124         String JavaDoc handle = request.getParameter("handle");
125         boolean showError = false;
126
127         // See if an item ID or Handle was passed in
128
Item itemToEdit = null;
129
130         if (internalID > 0)
131         {
132             itemToEdit = Item.find(context, internalID);
133
134             showError = (itemToEdit == null);
135         }
136         else if ((handle != null) && !handle.equals(""))
137         {
138             // resolve handle
139
DSpaceObject dso = HandleManager.resolveToObject(context, handle);
140
141             // make sure it's an ITEM
142
if ((dso != null) && (dso.getType() == Constants.ITEM))
143             {
144                 itemToEdit = (Item) dso;
145                 showError = false;
146             }
147             else
148             {
149                 showError = true;
150             }
151         }
152
153         // Show edit form if appropriate
154
if (itemToEdit != null)
155         {
156             // now check to see if person can edit item
157
checkEditAuthorization(context, itemToEdit);
158             showEditForm(context, request, response, itemToEdit);
159         }
160         else
161         {
162             if (showError)
163             {
164                 request.setAttribute("invalid.id", new Boolean JavaDoc(true));
165             }
166
167             JSPManager.showJSP(request, response, "/tools/get-item-id.jsp");
168         }
169     }
170
171     protected void doDSPost(Context context, HttpServletRequest JavaDoc request,
172             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
173             SQLException JavaDoc, AuthorizeException
174     {
175         // First, see if we have a multipart request (uploading a new bitstream)
176
String JavaDoc contentType = request.getContentType();
177
178         if ((contentType != null)
179                 && (contentType.indexOf("multipart/form-data") != -1))
180         {
181             // This is a multipart request, so it's a file upload
182
processUploadBitstream(context, request, response);
183
184             return;
185         }
186
187         /*
188          * Then we check for a "cancel" button - if it's been pressed, we simply
189          * return to the "find by handle/id" page
190          */

191         if (request.getParameter("submit_cancel") != null)
192         {
193             JSPManager.showJSP(request, response, "/tools/get-item-id.jsp");
194
195             return;
196         }
197
198         /*
199          * Respond to submitted forms. Each form includes an "action" parameter
200          * indicating what needs to be done (from the constants above.)
201          */

202         int action = UIUtil.getIntParameter(request, "action");
203
204         Item item = Item.find(context, UIUtil.getIntParameter(request,
205                 "item_id"));
206  
207         String JavaDoc handle = HandleManager.findHandle(context, item);
208
209         // now check to see if person can edit item
210
checkEditAuthorization(context, item);
211
212         request.setAttribute("item", item);
213         request.setAttribute("handle", handle);
214
215         switch (action)
216         {
217         case START_DELETE:
218
219             // Show "delete item" confirmation page
220
JSPManager.showJSP(request, response,
221                     "/tools/confirm-delete-item.jsp");
222
223             break;
224
225         case CONFIRM_DELETE:
226
227             // Delete the item - if "cancel" was pressed this would be
228
// picked up above
229
// FIXME: Don't know if this does all it should - remove Handle?
230
Collection[] collections = item.getCollections();
231
232             // Remove item from all the collections it's in
233
for (int i = 0; i < collections.length; i++)
234             {
235                 collections[i].removeItem(item);
236             }
237
238             JSPManager.showJSP(request, response, "/tools/get-item-id.jsp");
239             context.complete();
240
241             break;
242
243         case UPDATE_ITEM:
244             processUpdateItem(context, request, response, item);
245
246             break;
247
248         case START_WITHDRAW:
249
250             // Show "withdraw item" confirmation page
251
JSPManager.showJSP(request, response,
252                     "/tools/confirm-withdraw-item.jsp");
253
254             break;
255
256         case CONFIRM_WITHDRAW:
257
258             // Withdraw the item
259
item.withdraw();
260             JSPManager.showJSP(request, response, "/tools/get-item-id.jsp");
261             context.complete();
262
263             break;
264
265         case REINSTATE:
266             item.reinstate();
267             JSPManager.showJSP(request, response, "/tools/get-item-id.jsp");
268             context.complete();
269
270             break;
271
272         default:
273
274             // Erm... weird action value received.
275
log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
276                     .getRequestLogInfo(request)));
277             JSPManager.showIntegrityError(request, response);
278         }
279     }
280
281     /**
282      * Throw an exception if user isn't authorized to edit this item
283      *
284      * @param context
285      * @param item
286      */

287     private void checkEditAuthorization(Context c, Item item)
288             throws AuthorizeException, java.sql.SQLException JavaDoc
289     {
290         if (!item.canEdit())
291         {
292             int userID = 0;
293
294             // first, check if userid is set
295
if (c.getCurrentUser() != null)
296             {
297                 userID = c.getCurrentUser().getID();
298             }
299
300             // show an error or throw an authorization exception
301
throw new AuthorizeException("EditItemServlet: User " + userID
302                     + " not authorized to edit item " + item.getID());
303         }
304     }
305
306     /**
307      * Show the item edit form for a particular item
308      *
309      * @param context
310      * DSpace context
311      * @param request
312      * the HTTP request containing posted info
313      * @param response
314      * the HTTP response
315      * @param item
316      * the item
317      */

318     private void showEditForm(Context context, HttpServletRequest JavaDoc request,
319             HttpServletResponse JavaDoc response, Item item) throws ServletException JavaDoc,
320             IOException JavaDoc, SQLException JavaDoc, AuthorizeException
321     {
322         if ( request.getParameter("cc_license_url") != null )
323         {
324             // set or replace existing CC license
325
CreativeCommons.setLicense( context, item,
326                    request.getParameter("cc_license_url") );
327             context.commit();
328         }
329   
330         // Get the handle, if any
331
String JavaDoc handle = HandleManager.findHandle(context, item);
332
333         // Collections
334
Collection[] collections = item.getCollections();
335
336         // All DC types in the registry
337
MetadataField[] types = MetadataField.findAll(context);
338         
339         // Get a HashMap of metadata field ids and a field name to display
340
HashMap JavaDoc metadataFields = new HashMap JavaDoc();
341         
342         // Get all existing Schemas
343
MetadataSchema[] schemas = MetadataSchema.findAll(context);
344         for (int i = 0; i < schemas.length; i++)
345         {
346             String JavaDoc schemaName = schemas[i].getName();
347             // Get all fields for the given schema
348
MetadataField[] fields = MetadataField.findAllInSchema(context, schemas[i].getSchemaID());
349             for (int j = 0; j < fields.length; j++)
350             {
351                 Integer JavaDoc fieldID = new Integer JavaDoc(fields[j].getFieldID());
352                 String JavaDoc displayName = "";
353                 displayName = schemaName + "." + fields[j].getElement() + (fields[j].getQualifier() == null ? "" : "." + fields[j].getQualifier());
354                 metadataFields.put(fieldID, displayName);
355             }
356         }
357
358         request.setAttribute("item", item);
359         request.setAttribute("handle", handle);
360         request.setAttribute("collections", collections);
361         request.setAttribute("dc.types", types);
362         request.setAttribute("metadataFields", metadataFields);
363
364         JSPManager.showJSP(request, response, "/tools/edit-item-form.jsp");
365     }
366
367     /**
368      * Process input from the edit item form
369      *
370      * @param context
371      * DSpace context
372      * @param request
373      * the HTTP request containing posted info
374      * @param response
375      * the HTTP response
376      * @param item
377      * the item
378      */

379     private void processUpdateItem(Context context, HttpServletRequest JavaDoc request,
380             HttpServletResponse JavaDoc response, Item item) throws ServletException JavaDoc,
381             IOException JavaDoc, SQLException JavaDoc, AuthorizeException
382     {
383         String JavaDoc button = UIUtil.getSubmitButton(request, "submit");
384         /*
385          * "Cancel" handled above, so whatever happens, we need to update the
386          * item metadata. First, we remove it all, then build it back up again.
387          */

388         item.clearMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
389
390         // We'll sort the parameters by name. This ensures that DC fields
391
// of the same element/qualifier are added in the correct sequence.
392
// Get the parameters names
393
Enumeration JavaDoc unsortedParamNames = request.getParameterNames();
394
395         // Put them in a list
396
List JavaDoc sortedParamNames = new LinkedList JavaDoc();
397
398         while (unsortedParamNames.hasMoreElements())
399         {
400             sortedParamNames.add(unsortedParamNames.nextElement());
401         }
402
403         // Sort the list
404
Collections.sort(sortedParamNames);
405
406         Iterator JavaDoc iterator = sortedParamNames.iterator();
407
408         while (iterator.hasNext())
409         {
410             String JavaDoc p = (String JavaDoc) iterator.next();
411
412             if (p.startsWith("value"))
413             {
414                 /*
415                  * It's a metadata value - it will be of the form
416                  * value_element_1 OR value_element_qualifier_2 (the number
417                  * being the sequence number) We use a StringTokenizer to
418                  * extract these values
419                  */

420                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(p, "_");
421
422                 st.nextToken(); // Skip "value"
423

424                 String JavaDoc schema = st.nextToken();
425
426                 String JavaDoc element = st.nextToken();
427
428                 String JavaDoc qualifier = null;
429
430                 if (st.countTokens() == 2)
431                 {
432                     qualifier = st.nextToken();
433                 }
434
435                 String JavaDoc sequenceNumber = st.nextToken();
436
437                 // Get a string with "element" for unqualified or
438
// "element_qualifier"
439
String JavaDoc key = MetadataField.formKey(schema,element,qualifier);
440
441                 // Get the language
442
String JavaDoc language = request.getParameter("language_" + key + "_"
443                         + sequenceNumber);
444
445                 // Empty string language = null
446
if ((language != null) && language.equals(""))
447                 {
448                     language = null;
449                 }
450
451                 // Get the value
452
String JavaDoc value = request.getParameter(p).trim();
453
454                 // If remove button pressed for this value, we don't add it
455
// back to the item. We also don't add empty values.
456
if (!(value.equals("") || button.equals("submit_remove_" + key
457                         + "_" + sequenceNumber)))
458                 {
459                     // Value is empty, or remove button for this wasn't pressed
460
item.addMetadata(schema, element, qualifier, language, value);
461                 }
462             }
463             // only process bitstreams if admin
464
else if (p.startsWith("bitstream_name")
465                     && AuthorizeManager.isAdmin(context))
466             {
467                 // We have bitstream metadata
468
// First, get the bundle and bitstream ID
469
// Parameter name is bitstream_name_(bundleID)_(bitstreamID)
470
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(p, "_");
471
472                 // Ignore "bitstream" and "name"
473
st.nextToken();
474                 st.nextToken();
475
476                 // Bundle ID and bitstream ID next
477
int bundleID = Integer.parseInt(st.nextToken());
478                 int bitstreamID = Integer.parseInt(st.nextToken());
479
480                 Bundle bundle = Bundle.find(context, bundleID);
481                 Bitstream bitstream = Bitstream.find(context, bitstreamID);
482
483                 // Get the string "(bundleID)_(bitstreamID)" for finding other
484
// parameters related to this bitstream
485
String JavaDoc key = String.valueOf(bundleID) + "_" + bitstreamID;
486
487                 // Update bitstream metadata, or delete?
488
if (button.equals("submit_delete_bitstream_" + key))
489                 {
490                     // "delete" button pressed
491
bundle.removeBitstream(bitstream);
492
493                     // Delete bundle too, if empty
494
if (bundle.getBitstreams().length == 0)
495                     {
496                         item.removeBundle(bundle);
497                     }
498                 }
499                 else
500                 {
501                     // Update the bitstream metadata
502
String JavaDoc name = request.getParameter(p);
503                     String JavaDoc source = request.getParameter("bitstream_source_"
504                             + key);
505                     String JavaDoc desc = request.getParameter("bitstream_description_"
506                             + key);
507                     int formatID = UIUtil.getIntParameter(request,
508                             "bitstream_format_id_" + key);
509                     String JavaDoc userFormatDesc = request
510                             .getParameter("bitstream_user_format_description_"
511                                     + key);
512                     int primaryBitstreamID = UIUtil.getIntParameter(request,
513                             bundleID + "_primary_bitstream_id");
514
515                     // Empty strings become non-null
516
if (source.equals(""))
517                     {
518                         source = null;
519                     }
520
521                     if (desc.equals(""))
522                     {
523                         desc = null;
524                     }
525
526                     if (userFormatDesc.equals(""))
527                     {
528                         userFormatDesc = null;
529                     }
530
531                     bitstream.setName(name);
532                     bitstream.setSource(source);
533                     bitstream.setDescription(desc);
534                     bitstream
535                             .setFormat(BitstreamFormat.find(context, formatID));
536
537                     if (primaryBitstreamID > 0)
538                     {
539                         bundle.setPrimaryBitstreamID(primaryBitstreamID);
540                     }
541
542                     if (userFormatDesc != null)
543                     {
544                         bitstream.setUserFormatDescription(userFormatDesc);
545                     }
546
547                     bitstream.update();
548                     bundle.update();
549                 }
550             }
551         }
552
553         item.update();
554
555         /*
556          * Now respond to button presses, other than "Remove" or "Delete" button
557          * presses which were dealt with in the above loop.
558          */

559         if (button.equals("submit_addfield"))
560         {
561             // Adding a metadata field
562
int dcTypeID = UIUtil.getIntParameter(request, "addfield_dctype");
563             String JavaDoc value = request.getParameter("addfield_value").trim();
564             String JavaDoc lang = request.getParameter("addfield_language");
565
566             // Empty language = null
567
if (lang.equals(""))
568             {
569                 lang = null;
570             }
571
572             MetadataField field = MetadataField.find(context, dcTypeID);
573             MetadataSchema schema = MetadataSchema.find(context, field
574                     .getSchemaID());
575             item.addMetadata(schema.getName(), field.getElement(), field
576                     .getQualifier(), lang, value);
577             item.update();
578         }
579
580         if (button.equals("submit_addcc"))
581         {
582             // Show cc-edit page
583
request.setAttribute("item", item);
584             JSPManager
585                     .showJSP(request, response, "/tools/creative-commons-edit.jsp");
586         }
587         
588         if (button.equals("submit_addbitstream"))
589         {
590             // Show upload bitstream page
591
request.setAttribute("item", item);
592             JSPManager
593                     .showJSP(request, response, "/tools/upload-bitstream.jsp");
594         }
595         else
596         {
597             // Show edit page again
598
showEditForm(context, request, response, item);
599         }
600         
601         // update the item index
602
DSIndexer.reIndexContent(context, item);
603
604         // Complete transaction
605
context.complete();
606     }
607
608     /**
609      * Process the input from the upload bitstream page
610      *
611      * @param context
612      * current DSpace context
613      * @param request
614      * current servlet request object
615      * @param response
616      * current servlet response object
617      */

618     private void processUploadBitstream(Context context,
619             HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
620             throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
621             AuthorizeException
622     {
623         // Wrap multipart request to get the submission info
624
FileUploadRequest wrapper = new FileUploadRequest(request);
625         Bitstream b = null;
626
627         Item item = Item.find(context, UIUtil.getIntParameter(wrapper,
628                 "item_id"));
629
630         File JavaDoc temp = wrapper.getFile("file");
631
632         // Read the temp file as logo
633
InputStream JavaDoc is = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(temp));
634
635         // now check to see if person can edit item
636
checkEditAuthorization(context, item);
637
638         // do we already have an ORIGINAL bundle?
639
Bundle[] bundles = item.getBundles("ORIGINAL");
640
641         if (bundles.length < 1)
642         {
643             // set bundle's name to ORIGINAL
644
b = item.createSingleBitstream(is, "ORIGINAL");
645         }
646         else
647         {
648             // we have a bundle already, just add bitstream
649
b = bundles[0].createBitstream(is);
650         }
651
652         // Strip all but the last filename. It would be nice
653
// to know which OS the file came from.
654
String JavaDoc noPath = wrapper.getFilesystemName("file");
655
656         while (noPath.indexOf('/') > -1)
657         {
658             noPath = noPath.substring(noPath.indexOf('/') + 1);
659         }
660
661         while (noPath.indexOf('\\') > -1)
662         {
663             noPath = noPath.substring(noPath.indexOf('\\') + 1);
664         }
665
666         b.setName(noPath);
667         b.setSource(wrapper.getFilesystemName("file"));
668
669         // Identify the format
670
BitstreamFormat bf = FormatIdentifier.guessFormat(context, b);
671         b.setFormat(bf);
672         b.update();
673
674         item.update();
675
676         // Back to edit form
677
showEditForm(context, request, response, item);
678
679         // Remove temp file
680
temp.delete();
681
682         // Update DB
683
context.complete();
684     }
685 }
Popular Tags