View Javadoc

1   package org.sourceforge.vlibrary.user.forms;
2   
3   import java.util.ArrayList;
4   import java.util.StringTokenizer;
5   
6   import javax.servlet.http.HttpServletRequest;
7   
8   import org.apache.struts.action.ActionErrors;
9   import org.apache.struts.action.ActionMapping;
10  import org.apache.struts.action.ActionMessage;
11  import org.sourceforge.vlibrary.user.domain.Author;
12  import org.sourceforge.vlibrary.user.domain.Subject;
13  
14  /**
15   * @version $Revision$ $Date$
16   * Form bean for the Book edit page.  This form has the following fields:
17   * <ul>
18   * <li><b>title</b> - The title of the book [REQUIRED]
19   * <li><b>owner</b> - The id of the owning reader [REQUIRED -- COMPUTED]
20   * <li><b>ownerFirstName</b> The owner's first Name [REQUIRED]
21   * <li><b>ownerLastName</b> The owner's last Name [REQUIRED]
22   * <li><b>isbn</b> - - The ISBN number of the book [REQUIRED]
23   * <li><b>pub_date</b> - The publication date of the book
24   * <li><b>created</b> - The date the book was added to the library
25   * <li><b>authors</b> - Author(s) [Required]
26   * <li><b>authorString</b> - Author(s) full names \n-separated
27   * <li><b>subjects</b> - Subject Classification(s) [Required]
28   * <li><b>subjectString</b> - Subject Classification(s) \n-separated
29   * <li><b>id</b> - The ID of the book
30   * <li><b>subjectList</b> - ArrayList of all subjects for list box
31   * </ul>
32   */
33  public class BookForm extends LibraryForm {
34      private static final long serialVersionUID = 0;
35  
36      private String title = null;
37      private long id = 0;
38      private String publisher = null;
39      private String pub_date = null;
40      private String created = null;
41      private long owner = 0;
42      private String isbn = null;
43      private ArrayList<Author> authors = null;
44      private ArrayList<Subject> subjects = null;
45      private String ownerPhone = null;
46      private String action="Create";
47      private ArrayList<Subject> subjectList = null;
48  
49      public BookForm() {
50      }
51  
52      @Override
53      public String getClassName() {
54          return BookForm.class.getName();
55      }
56  
57      public ArrayList<Author> getAuthors() {
58          return authors;
59      }
60  
61      public void setAuthors(ArrayList<Author> authors) {
62          this.authors = authors;
63      }
64  
65      public String getCreated() {
66          return created;
67      }
68  
69      public void setCreated(String created) {
70          this.created = created;
71      }
72  
73      public long getId() {
74          return id;
75      }
76  
77      public void setId(long id) {
78          this.id = id;
79      }
80  
81      public String getIsbn() {
82          return isbn;
83      }
84  
85      public void setIsbn(String isbn) {
86          this.isbn = isbn;
87      }
88  
89      public long getOwner() {
90          return owner;
91      }
92  
93      public void setOwner(long owner) {
94          this.owner = owner;
95      }
96  
97      public String getPub_date() {
98          return pub_date;
99      }
100 
101     public void setPub_date(String pub_date) {
102         this.pub_date = pub_date;
103     }
104 
105     public String getPublisher() {
106         return publisher;
107     }
108 
109     public void setPublisher(String publisher) {
110         this.publisher = publisher;
111     }
112 
113     public ArrayList<Subject> getSubjects() {
114         return subjects;
115     }
116 
117     public void setSubjects(ArrayList<Subject> subjects) {
118         this.subjects = subjects;
119     }
120 
121     public String getTitle() {
122         return title;
123     }
124 
125     public void setTitle(String title) {
126         this.title = title;
127     }
128 
129     public String getAuthorString() {
130         if (authors == null) {
131             return null;
132         }
133         final StringBuffer buf = new StringBuffer();
134         Author au = null;
135         for (int i=0;i<authors.size();i++) {
136             au = authors.get(i);
137             buf.append(au.getFirstName());
138             buf.append(" ");
139             buf.append(au.getLastName());
140             buf.append("\n");
141         }
142 
143         return buf.toString();
144     }
145 
146     /**
147      * Takes String from Authors text area and fills authors ArrayList
148      * with author objects constructed from the names in the \n-delimited
149      * input string.<br>
150      * <strong>nb: ID fields in author objects will not be set </strong>.
151      * @param inString String -- \n-delimited list of author full names
152      */
153     public void setAuthorString(String inString) {
154         final StringTokenizer st = new StringTokenizer(inString,"\n");
155 
156         if (!st.hasMoreElements()) {
157             return;
158         }
159 
160         authors = null;
161         authors = new ArrayList<Author>();
162         String fullName = null;
163         String firstName = null;
164         String lastName = null;
165         int pos = 0;
166 
167         while (st.hasMoreElements()) {
168             fullName = st.nextToken();
169             pos = fullName.lastIndexOf(" ");
170 
171             if ( pos < 0 ) // if the line only contains one name, not firstName_space_lastName
172             {
173                 firstName = " ";
174 
175                 lastName = fullName;
176             } else {
177                 lastName = fullName.substring(pos+1);
178 
179                 firstName = fullName.substring(0,pos);
180             }
181 
182             final Author au = new Author(firstName,lastName);
183 
184             authors.add(au);
185         }
186     }
187 
188     public String getSubjectString() {
189         if (subjects == null) {
190             return null;
191         }
192 
193         final StringBuffer buf = new StringBuffer();
194         Subject su = null;
195 
196         for (int i=0;i<subjects.size();i++) {
197             su = subjects.get(i);
198             buf.append(su.getDescription());
199             buf.append("\n");
200         }
201 
202         return buf.toString();
203     }
204 
205     public String getEnumeratedSubjectString() {
206         if (subjects == null) {
207             return null;
208         }
209 
210         final StringBuffer buf = new StringBuffer();
211         Subject su = null;
212 
213         for (int i=0;i<subjects.size();i++) {
214             su = subjects.get(i);
215             buf.append(su.getDescription());
216             if (i < subjects.size() -1){
217                 buf.append(",  ");
218             }
219         }
220 
221         return buf.toString();
222     }
223 
224     public String getSubjectListString() {
225         if (subjectList == null) {
226             return null;
227         }
228         final StringBuffer buf = new StringBuffer();
229         Subject su = null;
230 
231         for (int i=0;i<subjectList.size();i++) {
232             su = subjectList.get(i);
233             buf.append(su.getDescription());
234             buf.append("\n");
235         }
236 
237         return buf.toString();
238     }
239 
240     /**
241      * Takes String from Subjects text area and fills subjects ArrayList
242      * with subject objects constructed from the descriptions in the
243      * \n-delimited input string. <br>
244      * <strong>nb: ID fields in subject objects will not be set </strong>.
245      * @param inString String -- \n-delimited list of author full names
246      */
247     public void setSubjectString(String inString) {
248         final StringTokenizer st = new StringTokenizer(inString,"\n");
249         if (!st.hasMoreElements()) {
250             return;
251         }
252         subjects = null;
253         subjects = new ArrayList<Subject>();
254 
255         while (st.hasMoreElements()) {
256             final Subject su = new Subject(st.nextToken());
257             subjects.add(su);
258         }
259     }
260 
261 
262     /**
263      * Validate the properties that have been set from this HTTP request,
264      * and return an <code>ActionErrors</code> object that encapsulates any
265      * validation errors that have been found.  If no errors are found, return
266      * <code>null</code> or an <code>ActionErrors</code> object with no
267      * recorded error messages.<br>
268      *
269      * Uses <code>LibraryManagerFacade.getReaderID()</code> to lookup and set <b>owner</b>
270      * field.
271      *
272      * @param mapping The mapping used to select this instance
273      * @param request The servlet request we are processing
274      */
275     @Override
276     public ActionErrors validate(ActionMapping mapping,
277             HttpServletRequest request) {
278         logger.debug("Entering validate");
279         final ActionErrors errors = new ActionErrors();
280 
281         if ((title == null) || (title.length() < 1)) {
282             errors.add("title",
283                     new ActionMessage("error.book.title.required"));
284         }
285 
286         validateIsbn( isbn.toUpperCase(), errors );
287 
288         if ( authors == null || authors.size()==0) {
289             errors.add("authors",
290                     new ActionMessage("error.book.author.required"));
291         }
292 
293         if (subjects == null || subjects.size()==0) {
294             errors.add("subjects",
295                     new ActionMessage("error.book.subject.required"));
296         }
297 
298         try {
299             if (!libraryManager.isUserIDValid(owner)) {
300                 errors.add("owner", new ActionMessage("error.book.owner.notFound"));
301             }
302         } catch (final Exception e) {
303             errors.add("owner",
304                     new ActionMessage("error.book.owner.lookup"));
305         }
306         logger.debug("Validate successful with " + errors.size() + " validation errors");
307 
308         return errors;
309     }
310 
311     /**
312      * Validate the ISBN
313      * Any error found is added to the errors ActionErrors
314      *
315      * @param isbn String -- The ISBN number to validate
316      * @param errors ActionErrors - errors ActionErrors for this form to include any validation error(s) found
317      *
318      */
319     public void validateIsbn(String isbn, ActionErrors errors) {
320 
321         if ((isbn == null) || (isbn.length() < 1)) {
322             errors.add("isbn",
323                     new ActionMessage("error.book.isbn.required"));
324 
325             return;
326         }
327 
328         final String strippedIsbn = stripIsbnDashesBlanks( isbn );
329 
330         if ( strippedIsbn.length() != 10 && strippedIsbn.length() != 13 ) {
331             errors.add("isbn3",
332                     new ActionMessage("error.book.isbn.invalid"));
333 
334             return;
335         }
336 
337         if ( strippedIsbn.length() == 10 && !isIsbn10Valid( strippedIsbn )) {
338             errors.add("isbn1",
339                     new ActionMessage("error.book.isbn.invalid"));
340 
341             return;
342         } else if ( strippedIsbn.length() == 13 && !isIsbn13Valid( strippedIsbn )) {
343             errors.add("isbn2",
344                     new ActionMessage("error.book.isbn.invalid"));
345 
346             return;
347         }
348     }
349 
350     /**
351      * Validate syntactically the ISBN 10 digits
352      *
353      * @see <a href="http://www.isbn-international.org/en/manual.html"> ISBN Specification</a>
354      *
355      * @return true if isbn is valid, false otherwise
356      *
357      * @param isbn String -- The ISBN number to validate
358      *
359      */
360     public boolean isIsbn10Valid(String isbn) {
361 
362         int isbnValue = 0;
363 
364         try {
365             for( int i=0; i <= isbn.length() -1; i++) {
366                 if (i == isbn.length() -1) {
367                     if (isbn.charAt(i) =='X') {
368                         isbnValue += 10;
369                     } else if ( !Character.isDigit(isbn.charAt(i))) {
370                         return false;
371                     } else {
372                         isbnValue += Character.digit(isbn.charAt(i), 10);
373                     }
374                 } else {
375                     if ( !Character.isDigit(isbn.charAt(i))) {
376                         return false;
377                     }
378 
379                     isbnValue += (10 - i) * Character.digit(isbn.charAt(i), 10);
380                 }
381             }
382         } catch( final Throwable ex) {
383             return false;
384         }
385 
386         if ( isbnValue <= 0 || isbnValue % 11 != 0) {
387             return false;
388         }
389 
390         return true;
391     }
392 
393     /**
394      * Validate syntactically the ISBN 13 digits
395      *
396      * @see <a href="http://www.isbn-international.org/en/manual.html"> ISBN Specification</a>
397      *
398      * @return true if isbn is valid, false otherwise
399      *
400      * @param isbn String -- The ISBN number to validate
401      *
402      */
403     public boolean isIsbn13Valid(String isbn) {
404 
405         int isbnValue = 0;
406 
407         try {
408             // the first *12* digits, not the last one
409             for( int i=0; i <= isbn.length() -2; i++) {
410                 if ( !Character.isDigit(isbn.charAt(i))) {
411                     return false;
412                 }
413 
414                 // each digit is alternately multiplied by 1 and 3 respectively,
415                 // starting with first (that is #0) digit
416                 if ( i % 2 == 0) {
417                     isbnValue += 1 * Character.digit(isbn.charAt(i), 10);
418                 } else {
419                     isbnValue += 3 * Character.digit(isbn.charAt(i), 10);
420                 }
421             }
422             int checkdigit = 10- isbnValue % 10;
423 
424             if (checkdigit == 10) {
425                 checkdigit = 0;
426             }
427 
428             if ( checkdigit != Character.digit(isbn.charAt(isbn.length() - 1), 10)) {
429                 return false;
430             }
431         } catch( final Throwable ex) {
432             return false;
433         }
434 
435         return true;
436     }
437 
438     /**
439      * Strip any dashes and/or blanks in the isbn
440      * so validation based on ISBN rules can be performed
441      *
442      * @param isbn String -- The ISBN number to strip dashes and/or blanks
443      *
444      */
445     public String stripIsbnDashesBlanks(String isbn) {
446 
447         final StringBuffer buf = new StringBuffer();
448 
449         for( int i=0; i <= isbn.length() -1; i++) {
450             if (isbn.charAt(i) != '-' && isbn.charAt(i) != ' ' ) {
451                 buf.append(isbn.charAt(i));
452             }
453         }
454         return buf.toString();
455     }
456 
457     public String getAction() {
458         return action;
459     }
460 
461     public void setAction(String action) {
462         this.action = action;
463     }
464 
465     public String getOwnerPhone() {
466         return ownerPhone;
467     }
468 
469     public void setOwnerPhone(String ownerPhone) {
470         this.ownerPhone = ownerPhone;
471     }
472 
473     /** Getter for property subjectList.
474      * @return Value of property subjectList.
475      */
476     public ArrayList<Subject> getSubjectList() {
477         return subjectList;
478     }
479 
480     /** Setter for property subjectList.
481      * @param subjectList New value of property subjectList.
482      */
483     public void setSubjectList(ArrayList<Subject> subjectList) {
484         this.subjectList = subjectList;
485     }
486 }