KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > app > webui > servlet > BrowseServlet


1 /*
2  * BrowseServlet.java
3  *
4  * Version: $Revision: 1.15 $
5  *
6  * Date: $Date: 2006/09/22 14:17:51 $
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;
41
42 import java.io.IOException JavaDoc;
43 import java.net.URLEncoder JavaDoc;
44 import java.sql.SQLException JavaDoc;
45
46 import javax.servlet.ServletException JavaDoc;
47 import javax.servlet.http.HttpServletRequest JavaDoc;
48 import javax.servlet.http.HttpServletResponse JavaDoc;
49
50 import org.apache.log4j.Logger;
51 import org.dspace.app.webui.util.JSPManager;
52 import org.dspace.app.webui.util.UIUtil;
53 import org.dspace.authorize.AuthorizeException;
54 import org.dspace.browse.Browse;
55 import org.dspace.browse.BrowseInfo;
56 import org.dspace.browse.BrowseScope;
57 import org.dspace.content.Collection;
58 import org.dspace.content.Community;
59 import org.dspace.content.Item;
60 import org.dspace.core.Constants;
61 import org.dspace.core.Context;
62 import org.dspace.core.LogManager;
63 import org.dspace.handle.HandleManager;
64
65 /**
66  * Servlet for browsing through indices. This can be used to browse authors,
67  * items by date, or items by title. In the deployment description, the initial
68  * parameter "browse" should be set to one of these values:
69  * <p>
70  * <ul>
71  * <lI><code>titles</code>- for browsing items by title (the default)</li>
72  * <lI><code>authors</code>- for browsing authors</li>
73  * <lI><code>dates</code>- for browsing items by date</li>
74  * </ul>
75  * <p>
76  * Hence there should be three instances of this servlet, one for each type of
77  * browse.
78  *
79  * @author Robert Tansley
80  * @version $Revision: 1.15 $
81  */

82 public class BrowseServlet extends DSpaceServlet
83 {
84     /** log4j category */
85     private static Logger log = Logger.getLogger(BrowseServlet.class);
86
87     /** Is this servlet for browsing authors? */
88     private boolean browseAuthors;
89
90     /** Is this servlet for browsing items by title? */
91     private boolean browseTitles;
92
93     /** Is this servlet for browsing items by date? */
94     private boolean browseDates;
95
96     /** Is this servlet for browsing items by subject? */
97     private boolean browseSubjects;
98
99     public void init()
100     {
101         // Sort out what we're browsing - default is titles
102
String JavaDoc browseWhat = getInitParameter("browse");
103
104         browseAuthors = ((browseWhat != null) && browseWhat
105                 .equalsIgnoreCase("authors"));
106         browseDates = ((browseWhat != null) && browseWhat
107                 .equalsIgnoreCase("dates"));
108         browseSubjects = ((browseWhat != null) && browseWhat
109                 .equalsIgnoreCase("subjects"));
110
111         browseTitles = ((!browseAuthors && !browseDates)&& !browseSubjects );
112     }
113
114     protected void doDSGet(Context context, HttpServletRequest JavaDoc request,
115             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
116             SQLException JavaDoc, AuthorizeException
117     {
118         // We will resolve the HTTP request parameters into a scope
119
BrowseScope scope = new BrowseScope(context);
120
121         // Will need to know whether to highlight the "focus" point
122
boolean highlight = false;
123
124         // Build up log information
125
String JavaDoc logInfo = "";
126
127         // For browse by date, we'll need to work out the URL query string to
128
// use when the user swaps the ordering, so that they stay at the same
129
// point in the index
130
String JavaDoc flipOrderingQuery = "";
131
132         // Grab HTTP request parameters
133
String JavaDoc focus = request.getParameter("focus");
134         String JavaDoc startsWith = request.getParameter("starts_with");
135         String JavaDoc top = request.getParameter("top");
136         String JavaDoc bottom = request.getParameter("bottom");
137
138         // The following three are specific to browsing items by date
139
String JavaDoc month = request.getParameter("month");
140         String JavaDoc year = request.getParameter("year");
141         String JavaDoc order = request.getParameter("order");
142
143         // For browse by date: oldest item first?
144
boolean oldestFirst = false;
145
146         if ((order != null) && order.equalsIgnoreCase("oldestfirst"))
147         {
148             oldestFirst = true;
149         }
150
151         if (browseDates && (year != null) && !year.equals("")
152                 && ((startsWith == null) || startsWith.equals("")))
153         {
154             // We're browsing items by date, the user hasn't typed anything
155
// into the "year" text box, and they've selected a year from
156
// the drop-down list. From this we work out where to start
157
// the browse.
158
startsWith = year;
159
160             if ((month != null) & !month.equals("-1"))
161             {
162                 // They've selected a month as well
163
if (month.length() == 1)
164                 {
165                     // Ensure double-digit month number
166
month = "0" + month;
167                 }
168
169                 startsWith = year + "-" + month;
170             }
171         }
172
173         // Set the scope according to the parameters passed in
174
if (focus != null)
175         {
176             // ----------------------------------------------
177
// Browse should start at a specified focus point
178
// ----------------------------------------------
179
if (browseAuthors||browseSubjects)
180             {
181                 // For browsing authors, focus is just a text value
182
scope.setFocus(focus);
183             }
184             else
185             {
186                 // For browsing items by title or date, focus is a Handle
187
Item item = (Item) HandleManager
188                         .resolveToObject(context, focus);
189
190                 if (item == null)
191                 {
192                     // Handle is invalid one. Show an error.
193
JSPManager.showInvalidIDError(request, response, focus,
194                             Constants.ITEM);
195
196                     return;
197                 }
198
199                 scope.setFocus(item);
200             }
201
202             // Will need to highlight the focus
203
highlight = true;
204
205             logInfo = "focus=" + focus + ",";
206
207             if (browseDates)
208             {
209                 // if the date order is flipped, we'll keep the same focus
210
flipOrderingQuery = "focus="
211                         + URLEncoder.encode(focus, Constants.DEFAULT_ENCODING)
212                         + "&amp;";
213             }
214         }
215         else if (startsWith != null)
216         {
217             // ----------------------------------------------
218
// Start the browse using user-specified text
219
// ----------------------------------------------
220
if (browseDates)
221             {
222                 // if the date order is flipped, we'll keep the same focus
223
flipOrderingQuery = "starts_with="
224                         + URLEncoder.encode(startsWith,
225                                 Constants.DEFAULT_ENCODING) + "&amp;";
226
227                 /*
228                  * When the user is browsing with the most recent items first,
229                  * the browse code algorithm doesn't quite do what some people
230                  * might expect. For example, if in the index there are entries:
231                  *
232                  * Mar-2000 15-Feb-2000 6-Feb-2000 15-Jan-2000
233                  *
234                  * and the user has selected "Feb 2000" as the start point for
235                  * the browse, the browse algorithm will start at the first
236                  * point in that index *after* "Feb 2000". "Feb 2000" would
237                  * appear in the index above between 6-Feb-2000 and 15-Jan-2000.
238                  * So, the browse code in this case will start the browse at
239                  * "15-Jan-2000". This isn't really what users are likely to
240                  * want: They're more likely to want the browse to start at the
241                  * first Feb 2000 date, i.e. 15-Feb-2000. A similar scenario
242                  * occurs when the user enters just a year. Our quick hack to
243                  * produce this behaviour is to add "-32" to the startsWith
244                  * variable, when sorting with most recent items first. This
245                  * means the browse code starts at the topmost item in the index
246                  * that matches the user's input, rather than the point in the
247                  * index where the user's input would appear.
248                  */

249                 if (!oldestFirst)
250                 {
251                     startsWith = startsWith + "-32";
252                 }
253             }
254
255             scope.setFocus(startsWith);
256             highlight = true;
257             logInfo = "starts_with=" + startsWith + ",";
258         }
259         else if ((top != null) || (bottom != null))
260         {
261             // ----------------------------------------------
262
// Paginating: put specified entry at top or bottom
263
// ----------------------------------------------
264
// Use a single value and a boolean to simplify the code below
265
String JavaDoc val = bottom;
266             boolean isTop = false;
267
268             if (top != null)
269             {
270                 val = top;
271                 isTop = true;
272             }
273
274             if (browseAuthors || browseSubjects)
275             {
276                 // Value will be a text value for author browse
277
scope.setFocus(val);
278             }
279             else
280             {
281                 // Value is Handle if we're browsing items by title or date
282
Item item = (Item) HandleManager.resolveToObject(context, val);
283
284                 if (item == null)
285                 {
286                     // Handle is invalid one. Show an error.
287
JSPManager.showInvalidIDError(request, response, focus,
288                             Constants.ITEM);
289
290                     return;
291                 }
292
293                 scope.setFocus(item);
294             }
295
296             // This entry appears at the top or bottom, and so needs to have
297
// 0 or 20 entries shown before it
298
scope.setNumberBefore(isTop ? 0 : 20);
299
300             logInfo = (isTop ? "top" : "bottom") + "=" + val + ",";
301
302             if (browseDates)
303             {
304                 // If the date order is flipped, we'll flip the table upside
305
// down - i.e. the top will become the bottom and the bottom
306
// the top.
307
if (top != null)
308                 {
309                     flipOrderingQuery = "bottom="
310                             + URLEncoder
311                                     .encode(top, Constants.DEFAULT_ENCODING)
312                             + "&amp;";
313                 }
314                 else
315                 {
316                     flipOrderingQuery = "top="
317                             + URLEncoder.encode(bottom,
318                                     Constants.DEFAULT_ENCODING) + "&amp;";
319                 }
320             }
321         }
322
323         // ----------------------------------------------
324
// If none of the above apply, no positioning parameters
325
// set - use start of index
326
// ----------------------------------------------
327
// Are we in a community or collection?
328
Community community = UIUtil.getCommunityLocation(request);
329         Collection collection = UIUtil.getCollectionLocation(request);
330
331         if (collection != null)
332         {
333             logInfo = logInfo + ",collection_id=" + collection.getID() + ",";
334             scope.setScope(collection);
335         }
336         else if (community != null)
337         {
338             logInfo = logInfo + ",community_id=" + community.getID() + ",";
339             scope.setScope(community);
340         }
341
342         BrowseInfo browseInfo;
343
344         try
345         {
346             // Query the browse index
347
if (browseAuthors)
348             {
349                 browseInfo = Browse.getAuthors(scope);
350             }
351             else if (browseDates)
352             {
353                 browseInfo = Browse.getItemsByDate(scope, oldestFirst);
354             }
355             else if (browseSubjects)
356             {
357                 browseInfo = Browse.getSubjects(scope);
358             }
359             else
360             {
361                 browseInfo = Browse.getItemsByTitle(scope);
362             }
363         }
364         catch (SQLException JavaDoc sqle)
365         {
366             // An invalid scope was given
367
JSPManager.showIntegrityError(request, response);
368             return;
369         }
370
371         // Write log entry
372
String JavaDoc what = "title";
373
374         if (browseAuthors)
375         {
376             what = "author";
377         }
378         else if (browseSubjects)
379         {
380             what = "subject";
381         }
382         else if (browseDates)
383         {
384             what = "date";
385         }
386
387         log.info(LogManager.getHeader(context, "browse_" + what, logInfo
388                 + "results=" + browseInfo.getResultCount()));
389
390         if (browseInfo.getResultCount() == 0)
391         {
392             // No results!
393
request.setAttribute("community", community);
394             request.setAttribute("collection", collection);
395
396             JSPManager.showJSP(request, response, "/browse/no-results.jsp");
397         }
398         else
399         {
400             // Work out what the query strings will be for the previous
401
// and next pages
402
if (!browseInfo.isFirst())
403             {
404                 // Not the first page, so we'll need a "previous page" button
405
// The top entry of the current page becomes the bottom
406
// entry of the "previous page"
407
String JavaDoc s;
408
409                 if (browseAuthors || browseSubjects) //aneesh
410
{
411                     s = (browseInfo.getStringResults())[0];
412                 }
413                 else
414                 {
415                     Item firstItem = (browseInfo.getItemResults())[0];
416                     s = firstItem.getHandle();
417                 }
418
419                 if (browseDates && oldestFirst)
420                 {
421                     // For browsing by date, oldest first, we need
422
// to add the ordering parameter
423
request.setAttribute("previous.query",
424                             "order=oldestfirst&amp;bottom="
425                                     + URLEncoder.encode(s,
426                                             Constants.DEFAULT_ENCODING));
427                 }
428                 else
429                 {
430                     request.setAttribute("previous.query", "bottom="
431                             + URLEncoder.encode(s, Constants.DEFAULT_ENCODING));
432                 }
433             }
434
435             if (!browseInfo.isLast())
436             {
437                 // Not the last page, so we'll need a "next page" button
438
// The bottom entry of the current page will be the top
439
// entry in the next page
440
String JavaDoc s;
441
442                 if (browseAuthors)
443                 {
444                     String JavaDoc[] authors = browseInfo.getStringResults();
445                     s = authors[authors.length - 1];
446                 }
447                 else if (browseSubjects)
448                 {
449                     String JavaDoc[] subjects = browseInfo.getStringResults();
450                     s = subjects[subjects.length - 1];
451                 }
452                 else
453                 {
454                     Item[] items = browseInfo.getItemResults();
455                     Item lastItem = items[items.length - 1];
456                     s = lastItem.getHandle();
457                 }
458
459                 if (browseDates && oldestFirst)
460                 {
461                     // For browsing by date, oldest first, we need
462
// to add the ordering parameter
463
request.setAttribute("next.query", "order=oldestfirst&amp;top="
464                             + URLEncoder.encode(s, Constants.DEFAULT_ENCODING));
465                 }
466                 else
467                 {
468                     request.setAttribute("next.query", "top="
469                             + URLEncoder.encode(s, Constants.DEFAULT_ENCODING));
470                 }
471             }
472
473             // Set appropriate attributes and forward to results page
474
request.setAttribute("community", community);
475             request.setAttribute("collection", collection);
476             request.setAttribute("browse.info", browseInfo);
477             request.setAttribute("highlight", new Boolean JavaDoc(highlight));
478
479             if (browseAuthors)
480             {
481                 JSPManager.showJSP(request, response, "/browse/authors.jsp");
482             }
483             else if (browseSubjects)
484             {
485                 JSPManager.showJSP(request, response, "/browse/subjects.jsp");
486             }
487             else if (browseDates)
488             {
489                 request.setAttribute("oldest.first", new Boolean JavaDoc(oldestFirst));
490                 request.setAttribute("flip.ordering.query", flipOrderingQuery);
491                 JSPManager.showJSP(request, response,
492                         "/browse/items-by-date.jsp");
493             }
494             else
495             {
496                 JSPManager.showJSP(request, response,
497                         "/browse/items-by-title.jsp");
498             }
499         }
500     }
501 }
502
Popular Tags