KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > app > statistics > ReportGenerator


1 /*
2  * ReportGenerator.java
3  *
4  * Version: $Revision: 1.4 $
5  *
6  * Date: $Date: 2006/10/13 13:04:07 $
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
41 package org.dspace.app.statistics;
42
43 import java.io.BufferedReader JavaDoc;
44 import java.io.File JavaDoc;
45 import java.io.FileOutputStream JavaDoc;
46 import java.io.FileReader JavaDoc;
47 import java.io.IOException JavaDoc;
48 import java.io.OutputStreamWriter JavaDoc;
49 import java.io.PrintWriter JavaDoc;
50 import java.sql.SQLException JavaDoc;
51 import java.text.ParseException JavaDoc;
52 import java.text.SimpleDateFormat JavaDoc;
53 import java.util.ArrayList JavaDoc;
54 import java.util.Arrays JavaDoc;
55 import java.util.Calendar JavaDoc;
56 import java.util.Date JavaDoc;
57 import java.util.GregorianCalendar JavaDoc;
58 import java.util.HashMap JavaDoc;
59 import java.util.Iterator JavaDoc;
60 import java.util.List JavaDoc;
61 import java.util.Map JavaDoc;
62 import java.util.StringTokenizer JavaDoc;
63 import java.util.regex.Matcher JavaDoc;
64 import java.util.regex.Pattern JavaDoc;
65
66 import org.dspace.content.DCValue;
67 import org.dspace.content.Item;
68 import org.dspace.core.ConfigurationManager;
69 import org.dspace.core.Context;
70 import org.dspace.handle.HandleManager;
71
72 /**
73  * This class performs the action of coordinating a usage report being
74  * generated using the standard internal aggregation file format as a basis.
75  * All it's configuration information must come from that file. There is the
76  * opportunity for different output format options such as HTML.
77  *
78  * Use the -help flag for more information
79  *
80  * @author Richard Jones
81  */

82 public class ReportGenerator
83 {
84     // set up our class globals
85

86     /////////////////
87
// aggregators
88
/////////////////
89

90     /** aggregator for all actions performed in the system */
91     private static Map JavaDoc actionAggregator = new HashMap JavaDoc();
92     
93     /** aggregator for all searches performed */
94     private static Map JavaDoc searchAggregator = new HashMap JavaDoc();
95     
96     /** aggregator for user logins */
97     private static Map JavaDoc userAggregator = new HashMap JavaDoc();
98     
99     /** aggregator for item views */
100     private static Map JavaDoc itemAggregator = new HashMap JavaDoc();
101     
102     /** aggregator for current archive state statistics */
103     private static Map JavaDoc archiveStats = new HashMap JavaDoc();
104     
105     
106     //////////////////
107
// statistics config data
108
//////////////////
109

110     /** bottom limit to output for search word analysis */
111     private static int searchFloor;
112     
113     /** bottom limit to output for item view analysis */
114     private static int itemFloor;
115     
116     /** number of items from most popular to be looked up in the database */
117     private static int itemLookup;
118     
119     /** mode to use for user email display */
120     private static String JavaDoc userEmail;
121     
122     /** URL of the service being analysed */
123     private static String JavaDoc url;
124     
125     /** Name of the service being analysed */
126     private static String JavaDoc name;
127
128     /** average number of views per item */
129     private static int avgItemViews;
130     
131     /** name of the server being analysed */
132     private static String JavaDoc serverName;
133     
134     /** start date of this report */
135     private static Date JavaDoc startDate = null;
136     
137     /** end date of this report */
138     private static Date JavaDoc endDate = null;
139     
140     /** the time taken to build the aggregation file from the log */
141     private static int processTime;
142   
143     /** the number of log lines analysed */
144     private static int logLines;
145     
146     /** the number of warnings encountered */
147     private static int warnings;
148     
149     /** the list of results to be displayed in the general summary */
150     private static List JavaDoc generalSummary = new ArrayList JavaDoc();
151     
152     //////////////////
153
// regular expressions
154
//////////////////
155

156     /** pattern that matches an unqualified aggregator property */
157     private static Pattern JavaDoc real = Pattern.compile("^(.+)=(.+)");
158     
159     //////////////////////////
160
// Miscellaneous variables
161
//////////////////////////
162

163    /** process timing clock */
164    private static Calendar JavaDoc startTime = null;
165    
166    /** a map from log file action to human readable action */
167    private static Map JavaDoc actionMap = new HashMap JavaDoc();
168    
169     /////////////////
170
// report generator config data
171
////////////////
172

173     /** the format of the report to be output */
174     private static String JavaDoc format = null;
175     
176     /** the input file to build the report from */
177     private static String JavaDoc input = null;
178     
179     /** the output file to which to write aggregation data */
180    private static String JavaDoc output = ConfigurationManager.getProperty("dspace.dir") +
181                             File.separator + "log" + File.separator + "report";
182    
183    /** the log file action to human readable action map */
184    private static String JavaDoc map = ConfigurationManager.getProperty("dspace.dir") +
185                             File.separator + "config" + File.separator + "dstat.map";
186    
187    
188     /**
189      * main method to be run from command line. See usage information for
190      * details as to how to use the command line flags
191      */

192     public static void main(String JavaDoc [] argv)
193         throws Exception JavaDoc, SQLException JavaDoc
194     {
195         // create context as super user
196
Context context = new Context();
197         context.setIgnoreAuthorization(true);
198         
199         String JavaDoc myFormat = null;
200         String JavaDoc myInput = null;
201         String JavaDoc myOutput = null;
202         String JavaDoc myMap = null;
203         
204         // read in our command line options
205
for (int i = 0; i < argv.length; i++)
206         {
207             if (argv[i].equals("-format"))
208             {
209                 myFormat = argv[i+1].toLowerCase();
210             }
211             
212             if (argv[i].equals("-in"))
213             {
214                 myInput = argv[i+1];
215             }
216             
217             if (argv[i].equals("-out"))
218             {
219                 myOutput = argv[i+1];
220             }
221             
222             if (argv[i].equals("-map"))
223             {
224                 myMap = argv[i+1];
225             }
226             
227             if (argv[i].equals("-help"))
228             {
229                 usage();
230                 System.exit(0);
231             }
232         }
233         
234         processReport(context, myFormat, myInput, myOutput, myMap);
235     }
236     
237     /**
238      * using the pre-configuration information passed here, read in the
239      * aggregation data and output a file containing the report in the
240      * requested format
241      *
242      * @param context the DSpace context in which this action is performed
243      * @param myFormat the desired output format (currently on HTML supported)
244      * @param myInput the aggregation file to be turned into a report
245      * @param myOutput the file into which to write the report
246      */

247     public static void processReport(Context context, String JavaDoc myFormat,
248                                      String JavaDoc myInput, String JavaDoc myOutput,
249                                      String JavaDoc myMap)
250         throws Exception JavaDoc, SQLException JavaDoc
251     {
252         startTime = new GregorianCalendar JavaDoc();
253         
254         // set the parameters for this analysis
255
setParameters(myFormat, myInput, myOutput, myMap);
256         
257         // pre prepare our standard file readers and buffered readers
258
FileReader JavaDoc fr = null;
259         BufferedReader JavaDoc br = null;
260         
261         // read the input file
262
readInput(input);
263         
264         // load the log file action to human readable action map
265
readMap(map);
266         
267         // create the relevant report type
268
// FIXME: at the moment we only support HTML report generation
269
Report report = null;
270         if (format.equals("html"))
271         {
272             report = new HTMLReport();
273         }
274         
275         report.setStartDate(startDate);
276         report.setEndDate(endDate);
277         report.setMainTitle(name, serverName);
278         
279         // define our standard variables for re-use
280
// FIXME: we probably don't need these once we've finished re-factoring
281
Iterator JavaDoc keys = null;
282         int i = 0;
283         String JavaDoc explanation = null;
284         int value;
285         
286         // FIXME: All of these sections should probably be buried in their own
287
// custom methods
288

289         Statistics overview = new Statistics();
290         
291         overview.setSectionHeader("General Overview");
292         
293         Iterator JavaDoc summaryEntries = generalSummary.iterator();
294         while (summaryEntries.hasNext())
295         {
296             String JavaDoc entry = (String JavaDoc) summaryEntries.next();
297             if (actionAggregator.containsKey(entry))
298             {
299                 int count = Integer.parseInt((String JavaDoc) actionAggregator.get(entry));
300                 overview.add(new Stat(translate(entry), count));
301             }
302         }
303         
304         report.addBlock(overview);
305         
306         // prepare the archive statistics package
307
if (archiveStats.size() > 0)
308         {
309             Statistics archiveInfo = prepareStats(archiveStats, true, false);
310             archiveInfo.setSectionHeader("Archive Information");
311             archiveInfo.setStatName("Content Type");
312             archiveInfo.setResultName("Number of items");
313         
314             report.addBlock(archiveInfo);
315         }
316         
317         
318         
319         // process the items in preparation to be displayed. This includes sorting
320
// by view number, building the links, and getting further info where
321
// necessary
322
Statistics viewedItems = new Statistics("Item/Handle", "Number of views", itemFloor);
323         viewedItems.setSectionHeader("Items Viewed");
324         
325         Stat[] items = new Stat[itemAggregator.size()];
326         
327         keys = itemAggregator.keySet().iterator();
328         i = 0;
329         while (keys.hasNext())
330         {
331             String JavaDoc key = (String JavaDoc) keys.next();
332             String JavaDoc link = url + "handle/" + key;
333             value = Integer.parseInt((String JavaDoc) itemAggregator.get(key));
334             items[i] = new Stat(key, value, link);
335             i++;
336         }
337         
338         Arrays.sort(items);
339         
340         String JavaDoc info = null;
341         for (i = 0; i < items.length; i++)
342         {
343             if (i < itemLookup)
344             {
345                 info = getItemInfo(context, items[i].getKey());
346             }
347                
348             // if we get something back from the db then set it as the key,
349
// else just use the link
350
if (info != null)
351             {
352                 items[i].setKey(info + " (" + items[i].getKey() + ")");
353             }
354             else
355             {
356                 items[i].setKey(items[i].getReference());
357             }
358             
359             // reset the info register
360
info = null;
361         }
362         
363         viewedItems.add(items);
364         
365         report.addBlock(viewedItems);
366         
367         // prepare a report of the full action statistics
368
Statistics fullInfo = prepareStats(actionAggregator, true, true);
369         fullInfo.setSectionHeader("All Actions Performed");
370         fullInfo.setStatName("Action");
371         fullInfo.setResultName("Number of times");
372         
373         report.addBlock(fullInfo);
374         
375         // prepare the user login statistics package
376
if (!userEmail.equals("off"))
377         {
378             Statistics userLogins = prepareStats(userAggregator, true, false);
379             userLogins.setSectionHeader("User Logins");
380             userLogins.setStatName("User");
381             userLogins.setResultName("Number of logins");
382             if (userEmail.equals("alias"))
383             {
384                 explanation = "(distinct addresses)";
385                 userLogins.setExplanation(explanation);
386             }
387         
388             report.addBlock(userLogins);
389         }
390
391         // prepare the search word statistics package
392
Statistics searchWords = prepareStats(searchAggregator, true, false);
393         searchWords.setSectionHeader("Words Searched");
394         searchWords.setStatName("Word");
395         searchWords.setResultName("Number of searches");
396         searchWords.setFloor(searchFloor);
397         
398         report.addBlock(searchWords);
399         
400         // FIXME: because this isn't an aggregator it can't be passed to
401
// prepareStats; should we overload this method for use with this kind
402
// of data?
403
// prepare the average item views statistics
404
if (avgItemViews > 0)
405         {
406             Statistics avg = new Statistics();
407             avg.setSectionHeader("Averaging Information");
408
409             Stat[] average = new Stat[1];
410         
411             average[0] = new Stat("Average views per item", avgItemViews);
412             avg.add(average);
413             report.addBlock(avg);
414         }
415       
416         
417         // prepare the log line level statistics
418
// FIXME: at the moment we only know about warnings, but future versions
419
// should aggregate all log line levels and display here
420
Statistics levels = new Statistics("Level", "Number of lines");
421         levels.setSectionHeader("Log Level Information");
422         
423         Stat[] level = new Stat[1];
424         level[0] = new Stat("Warnings", warnings);
425         
426         levels.add(level);
427         
428         report.addBlock(levels);
429         
430         // get the display processing time information
431
Calendar JavaDoc endTime = new GregorianCalendar JavaDoc();
432         long timeInMillis = (endTime.getTimeInMillis() - startTime.getTimeInMillis());
433         int outputProcessTime = (new Long JavaDoc(timeInMillis).intValue() / 1000);
434         
435         // prepare the processing information statistics
436
Statistics process = new Statistics("Operation", "");
437         process.setSectionHeader("Processing Information");
438         
439         Stat[] proc = new Stat[3];
440         proc[0] = new Stat("Log Processing Time", processTime);
441         proc[0].setUnits("seconds");
442         proc[1] = new Stat("Output Processing Time", outputProcessTime);
443         proc[1].setUnits("seconds");
444         proc[2] = new Stat("Log File Lines Analysed", logLines);
445         proc[2].setUnits("lines");
446         
447         process.add(proc);
448         
449         report.addBlock(process);
450         
451         // finally write the string into the output file
452
try
453         {
454             FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(output);
455             OutputStreamWriter JavaDoc osr = new OutputStreamWriter JavaDoc(fos, "UTF-8");
456             PrintWriter JavaDoc out = new PrintWriter JavaDoc(osr);
457             out.write(report.render());
458             out.close();
459         }
460         catch (IOException JavaDoc e)
461         {
462             System.out.println("Unable to write to output file " + output);
463             System.exit(0);
464         }
465         
466         return;
467     }
468     
469     
470     /**
471      * a standard stats block preparation method for use when an aggregator
472      * has to be put out in its entirity. This method will not be able to
473      * deal with complex cases, although it will perform sorting by value and
474      * translations as per the map file if requested
475      *
476      * @param aggregator the aggregator that should be converted
477      * @param sort should the resulting stats be sorted by value
478      * @param translate translate the stat name using the map file
479      *
480      * @return a Statistics object containing all the relevant information
481      */

482     public static Statistics prepareStats(Map JavaDoc aggregator, boolean sort, boolean translate)
483     {
484         Stat[] stats = new Stat[aggregator.size()];
485         if (aggregator.size() > 0)
486         {
487             Iterator JavaDoc keys = aggregator.keySet().iterator();
488             int i = 0;
489             while (keys.hasNext())
490             {
491                 String JavaDoc key = (String JavaDoc) keys.next();
492                 int value = Integer.parseInt((String JavaDoc) aggregator.get(key));
493                 if (translate)
494                 {
495                     stats[i] = new Stat(translate(key), value);
496                 }
497                 else
498                 {
499                     stats[i] = new Stat(key, value);
500                 }
501                 i++;
502             }
503             
504             if (sort)
505             {
506                 Arrays.sort(stats);
507             }
508         }
509         
510         // add the results to the statistics object
511
Statistics statistics = new Statistics();
512         statistics.add(stats);
513         
514         return statistics;
515     }
516     
517     
518     /**
519      * look the given text up in the action map table and return a translated
520      * value if one exists. If no translation exists the original text is
521      * returned
522      *
523      * @param text the text to be translated
524      *
525      * @return a string containing either the translated text or the original
526      * text
527      */

528     public static String JavaDoc translate(String JavaDoc text)
529     {
530         if (actionMap.containsKey(text))
531         {
532             return (String JavaDoc) actionMap.get(text);
533         }
534         else
535         {
536             return text;
537         }
538     }
539     
540     
541     /**
542      * read in the action map file which converts log file line actions into
543      * actions which are more understandable to humans
544      *
545      * @param map the map file
546      */

547     public static void readMap(String JavaDoc map)
548         throws IOException JavaDoc
549     {
550         FileReader JavaDoc fr = null;
551         BufferedReader JavaDoc br = null;
552         
553         // read in the map file, printing a warning if none is found
554
String JavaDoc record = null;
555         try
556         {
557             fr = new FileReader JavaDoc(map);
558             br = new BufferedReader JavaDoc(fr);
559         }
560         catch (IOException JavaDoc e)
561         {
562             System.err.println("Failed to read map file: log file actions will be displayed without translation");
563             return;
564         }
565         
566         // loop through the map file and read in the values
567
while ((record = br.readLine()) != null)
568         {
569             Matcher JavaDoc matchReal = real.matcher(record);
570             
571             // if the line is real then read it in
572
if (matchReal.matches())
573             {
574                 actionMap.put(matchReal.group(1).trim(), matchReal.group(2).trim());
575             }
576         }
577     }
578     
579     
580     /**
581      * set the passed parameters up as global class variables. This has to
582      * be done in a separate method because the API permits for running from
583      * the command line with args or calling the processReport method statically
584      * from elsewhere
585      *
586      * @param myFormat the log file directory to be analysed
587      * @param myInput regex for log file names
588      * @param myOutput config file to use for dstat
589      * @param myMap the action map file to use for translations
590      */

591     public static void setParameters(String JavaDoc myFormat, String JavaDoc myInput,
592                                     String JavaDoc myOutput, String JavaDoc myMap)
593     {
594         if (myFormat != null)
595         {
596             format = myFormat;
597         }
598         
599         if (myInput != null)
600         {
601             input = myInput;
602         }
603         
604         if (myOutput != null)
605         {
606             output = myOutput;
607         }
608         
609         if (myMap != null)
610         {
611             map = myMap;
612         }
613         
614         return;
615     }
616     
617     
618     /**
619      * read the input file and populate all the class globals with the contents
620      * The values that come from this file form the basis of the analysis report
621      *
622      * @param input the aggregator file
623      */

624     public static void readInput(String JavaDoc input)
625         throws IOException JavaDoc, ParseException JavaDoc
626     {
627         FileReader JavaDoc fr = null;
628         BufferedReader JavaDoc br = null;
629         
630         // read in the analysis information, throwing an error if we fail to open
631
// the given file
632
String JavaDoc record = null;
633         try
634         {
635             fr = new FileReader JavaDoc(input);
636             br = new BufferedReader JavaDoc(fr);
637         }
638         catch (IOException JavaDoc e)
639         {
640             System.out.println("Failed to read input file");
641             System.exit(0);
642         }
643         
644         // FIXME: although this works, it is not very elegant
645
// loop through the aggregator file and read in the values
646
while ((record = br.readLine()) != null)
647         {
648             // match real lines
649
Matcher JavaDoc matchReal = real.matcher(record);
650             
651             // pre-prepare our input strings
652
String JavaDoc section = null;
653             String JavaDoc key = null;
654             String JavaDoc value = null;
655             
656             // temporary string to hold the left hand side of the equation
657
String JavaDoc left = null;
658             
659             // match the line or skip this record
660
if (matchReal.matches())
661             {
662                 // lift the values out of the matcher's result groups
663
left = matchReal.group(1).trim();
664                 value = matchReal.group(2).trim();
665                 
666                 // now analyse the left hand side, splitting by ".", taking the
667
// first token as the section and the remainder of the string
668
// as they key if it exists
669
StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(left, ".");
670                 int numTokens = tokens.countTokens();
671                 if (tokens.hasMoreTokens())
672                 {
673                     section = tokens.nextToken();
674                     if (numTokens > 1)
675                     {
676                         key = left.substring(section.length() + 1);
677                     }
678                     else
679                     {
680                         key = "";
681                     }
682                 }
683             }
684             else
685             {
686                 continue;
687             }
688             
689             // if the line is real, then we carry on
690

691             // first initialise a date format object to do our date processing
692
// if necessary
693
SimpleDateFormat JavaDoc sdf = new SimpleDateFormat JavaDoc("dd'/'MM'/'yyyy");
694             
695             // read the analysis contents in
696
if (section.equals("archive"))
697             {
698                 archiveStats.put(key, value);
699             }
700             
701             if (section.equals("action"))
702             {
703                 actionAggregator.put(key, value);
704             }
705             
706             if (section.equals("user"))
707             {
708                 userAggregator.put(key, value);
709             }
710             
711             if (section.equals("search"))
712             {
713                 searchAggregator.put(key, value);
714             }
715             
716             if (section.equals("item"))
717             {
718                 itemAggregator.put(key, value);
719             }
720             
721             // read the config details used to make this report in
722
if (section.equals("user_email"))
723             {
724                 userEmail = value;
725             }
726             
727             if (section.equals("item_floor"))
728             {
729                 itemFloor = Integer.parseInt(value);
730             }
731             
732             if (section.equals("search_floor"))
733             {
734                 searchFloor = Integer.parseInt(value);
735             }
736             
737             if (section.equals("host_url"))
738             {
739                 url = value;
740             }
741             
742             if (section.equals("item_lookup"))
743             {
744                 itemLookup = Integer.parseInt(value);
745             }
746             
747             if (section.equals("avg_item_views"))
748             {
749                 try
750                 {
751                     avgItemViews = Integer.parseInt(value);
752                 }
753                 catch (NumberFormatException JavaDoc e)
754                 {
755                     avgItemViews = 0;
756                 }
757             }
758             
759             if (section.equals("server_name"))
760             {
761                 serverName = value;
762             }
763             
764             if (section.equals("service_name"))
765             {
766                 name = value;
767             }
768              
769             if (section.equals("start_date"))
770             {
771                 startDate = sdf.parse(value);
772             }
773             
774             if (section.equals("end_date"))
775             {
776                 endDate = sdf.parse(value);
777             }
778             
779             if (section.equals("analysis_process_time"))
780             {
781                 processTime = Integer.parseInt(value);
782             }
783             
784             if (section.equals("general_summary"))
785             {
786                 generalSummary.add(value);
787             }
788             
789             if (section.equals("log_lines"))
790             {
791                 logLines = Integer.parseInt(value);
792             }
793             
794             if (section.equals("warnings"))
795             {
796                 warnings = Integer.parseInt(value);
797             }
798         }
799
800         // close the inputs
801
br.close();
802         fr.close();
803     }
804     
805     /**
806      * get the information for the item with the given handle
807      *
808      * @param context the DSpace context we are operating under
809      * @param handle the handle of the item being looked up, in the form
810      * 1234/567 and so forth
811      *
812      * @return a string containing a reference (almost citation) to the
813      * article
814      */

815     public static String JavaDoc getItemInfo(Context context, String JavaDoc handle)
816         throws SQLException JavaDoc
817     {
818         Item item = null;
819         
820         // ensure that the handle exists
821
try
822         {
823             item = (Item) HandleManager.resolveToObject(context, handle);
824         }
825         catch (Exception JavaDoc e)
826         {
827             return null;
828         }
829         
830         // if no handle that matches is found then also return null
831
if (item == null)
832         {
833             return null;
834         }
835         
836         // build the referece
837
// FIXME: here we have blurred the line between content and presentation
838
// and it should probably be un-blurred
839
DCValue[] title = item.getDC("title", null, Item.ANY);
840         DCValue[] author = item.getDC("contributor", "author", Item.ANY);
841         
842         StringBuffer JavaDoc authors = new StringBuffer JavaDoc();
843         if (author.length > 0)
844         {
845             authors.append("(" + author[0].value);
846         }
847         if (author.length > 1)
848         {
849             authors.append(" et al");
850         }
851         if (author.length > 0)
852         {
853            authors.append(")");
854         }
855         
856         String JavaDoc content = title[0].value + " " + authors.toString();
857         
858         return content;
859     }
860     
861     
862     /**
863      * output the usage information to the terminal
864      */

865     public static void usage()
866     {
867         String JavaDoc usage = "Usage Information:\n" +
868                         "ReportGenerator [options [parameters]]\n" +
869                         "-format [output format]\n" +
870                             "\tRequired\n" +
871                             "\tSpecify the format that you would like the output in\n" +
872                             "\tOptions:\n" +
873                             "\t\thtml\n" +
874                         "-in [aggregation file]\n" +
875                             "\tRequired\n" +
876                             "\tSpecify the aggregation data file to display\n" +
877                         "-out [output file]\n" +
878                             "\tOptional\n" +
879                             "\tSpecify the file to output the report to\n" +
880                             "\tDefault uses [dspace log directory]/report\n" +
881                         "-map [map file]\n" +
882                             "\tOptional\n" +
883                             "\tSpecify the map file to translate log file actions into human readable actions\n" +
884                             "\tDefault uses [dspace config directory]/dstat.map\n" +
885                         "-help\n" +
886                             "\tdisplay this usage information\n";
887         
888         System.out.println(usage);
889     }
890 }
891
Popular Tags