Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/clra/web/MemberNameFormatSelectorTag.java


1   /*
2    * Copyright (c) Carnegie Lake Rowing Association 2002. All rights reserved.
3    * Distributed under the GPL license. See doc/COPYING.
4    * $RCSfile: MemberNameFormatSelectorTag.java,v $
5    * $Date: 2003/02/26 03:38:46 $
6    * $Revision: 1.3 $
7    */
8   
9   package com.clra.web;
10  
11  import com.clra.util.ErrorUtils;
12  import java.io.IOException;
13  import java.io.Serializable;
14  import java.util.HashMap;
15  import java.util.Hashtable;
16  import java.util.Iterator;
17  import java.util.Map;
18  import javax.servlet.http.HttpServletRequest;
19  import javax.servlet.http.HttpServletResponse;
20  import javax.servlet.http.HttpUtils;
21  import javax.servlet.jsp.JspException;
22  import javax.servlet.jsp.JspWriter;
23  import javax.servlet.jsp.PageContext;
24  import javax.servlet.jsp.tagext.TagSupport;
25  import org.apache.log4j.Category;
26  import org.apache.struts.util.MessageResources;
27  import org.apache.struts.util.ResponseUtils;
28  
29  /**
30   * Allows the user to specify whether names should be formated according to
31   * <tt>MemberNameFormat.FIRSTLAST</tt> or <tt>MemberNameFormat.LASTFIRST</tt>.
32   *
33   * @author <a mailto:"rphall@pluto.njcc.com">Rick Hall</a>
34   * @version $Revision: 1.3 $ $Date: 2003/02/26 03:38:46 $
35   */
36  public class MemberNameFormatSelectorTag extends TagSupport {
37  
38    private final static String base= MemberNameFormatSelectorTag.class.getName();
39    private final static Category theLog = Category.getInstance( base );
40  
41    /** The message resources for this package */
42    protected static MessageResources messages =
43      MessageResources.getMessageResources("com.clra.web.clra");
44  
45    /** The cached value of the groups used by this selector */
46    private static Map _groups = null;
47    static {
48      _groups = new HashMap();
49      final String PN_GROUP_PREFIX = "nameformat.0";
50      for ( int i=2; i<10; i++ ) {
51        Integer key = new Integer( i );
52        String PN = PN_GROUP_PREFIX + i;
53        String lbl = messages.getMessage( PN );
54        _groups.put( key, lbl );
55      }
56    }
57  
58    /** The groups used by this selector */
59    protected static Map groups() {
60      return _groups;
61    }
62  
63    /** The context-relative URI */
64    protected String page = null;
65  
66    /** The currently selected group (2 - 9) */
67    private Integer currentGroup = null;
68  
69    /** Return the context-relative URI */
70    public String getPage() {
71      return (this.page);
72    }
73  
74    /** Set the context-relative URI */
75    public void setPage(String page) {
76      this.page = page;
77    }
78  
79    /** Return the currently selected group (2 - 9, or null) */
80    public Integer getCurrentGroup() {
81      return this.currentGroup;
82    }
83  
84    /** Set the currently selected group (2 - 9, or null) */
85    public void setCurrentGroup( Integer currentGroup ) throws JspException {
86      if ( currentGroup != null ) {
87          if ( currentGroup.intValue() < 2 || currentGroup.intValue() > 9 ) {
88          String msg = messages.getMessage(
89              "nameselector.badcurrentGroup", currentGroup );
90          throw new JspException(msg);
91        }
92      }
93      this.currentGroup = currentGroup;
94    }
95  
96    /**
97     * A utility which determines what group should be currently selected
98     * based on the page context. The algorithm is:<ol>
99     * <li>Check for a request parameter named INameList.AN_GROUP. If
100    * found, and it is a valid Integer in the range 2 - 9, use it.</li>
101    * <li>Check for a request attribute named INameList.AN_GROUP. If
102    * found, and it is valid, use it.</li>
103    * <li>Check for a session attribute named INameList.AN_GROUP. If
104    * found, and it is valid, use it.</li>
105    * <li>If a valid group hasn't been determined yet, return the index
106    * of the first group, <tt>ABC</tt> (index 2).</li>
107    * </ol>
108    */
109   public static Integer groupFromContext( PageContext context ) {
110 
111     final String NAME = INameList.AN_GROUP;
112     Integer retVal = null;
113 
114     // Try request parameter first
115     try {
116       String s = context.getRequest().getParameter(NAME);
117       if ( s != null ) {
118         retVal = Integer.valueOf(s);
119         if ( retVal.intValue() < 2 || retVal.intValue() > 9 ) {
120           throw new IllegalArgumentException( "bad group == " + retVal );
121         }
122       }
123     }
124     catch( Exception x ) {
125       String msg = ErrorUtils.createDbgMsg( "requestParameter: " + NAME, x );
126       theLog.error( msg, x );
127     }
128 
129     // Try request attribute second
130     try {
131       if ( retVal == null ) {
132         Object o = context.getRequest().getAttribute(NAME);
133         if ( o != null && o instanceof Integer ) {
134           retVal = (Integer) o;
135           if ( retVal.intValue() < 2 || retVal.intValue() > 9 ) {
136             throw new IllegalArgumentException( "bad group == " + retVal );
137           } // if invalid Integer
138         } // if o
139       } // if null retVal
140     } // try
141     catch( Exception x ) {
142       String msg = ErrorUtils.createDbgMsg( "requestAttribute: " + NAME, x );
143       theLog.error( msg, x );
144     }
145     
146     // Try session attribute third
147     try {
148       if ( retVal == null ) {
149         Object o = context.getSession().getAttribute(NAME);
150         if ( o != null && o instanceof Integer ) {
151           retVal = (Integer) o;
152           if ( retVal.intValue() < 2 || retVal.intValue() > 9 ) {
153             throw new IllegalArgumentException( "bad group == " + retVal );
154           } // if valid Integer
155         } // if o
156       } // if null retVal
157     } // try
158     catch( Exception x ) {
159       String msg = ErrorUtils.createDbgMsg( "sessionAttribute: " + NAME, x );
160       theLog.error( msg, x );
161     }
162 
163     // Use the first group as a fallback
164     if ( retVal == null ) {
165       retVal = new Integer( 2 );
166     }
167 
168     return retVal;
169   } // groupFromContext(PageContext)
170 
171   /**
172    * A utility which resets request and session attributes so that only
173    * the session attribute AN_GROUP holds the currently selected name.
174    * The algorithm is:<ol>
175    * <li>Check for a request attribute named INameList.AN_GROUP. If
176    * found, remove it.</li>
177    * <li>Check for a session attribute named INameList.AN_GROUP. If
178    * found, reset to the specified value; otherwise create and set it.</li>
179    * </ol>
180    * If the specified name is invalid (not between 2 - 9, inclusive),
181    * no action is taken and an error is logged.
182    */
183   public static void resetGroupInContexts(PageContext context, Integer group) {
184 
185     // Check the context and group.
186     // If either is invalid, log an error and null both as a flag.
187     if ( context == null || group == null
188         || group.intValue() < 2 || group.intValue() > 9 ) {
189       theLog.error( "invalid context/group == " + context + "/" + group );
190       context = null;
191       group = null;
192     }
193 
194     final String NAME = INameList.AN_GROUP;
195 
196     // Reset the request attribute
197     if ( context != null ) {
198       context.getRequest().removeAttribute(NAME);
199     }
200 
201     // Set the session attribute
202     if ( context != null ) {
203       context.getSession().setAttribute(NAME,group);
204     }
205 
206     return;
207   } // resetGroupInContexts(PageContext,Integer)
208 
209   /** Form a query string from current parameter and the specified group */
210   protected String createQueryString( int group, Hashtable queryParams ) {
211 
212     // Preconditions
213     if ( group < 2 || group > 9 ) {
214       throw new IllegalArgumentException( "invalid group == " + group );
215     }
216     if ( queryParams == null ) {
217       throw new IllegalArgumentException( "null queryParams" );
218     }
219 
220     StringBuffer sb = new StringBuffer();
221     sb.append( "?" );
222 
223     // Overwrite existing query params related to this control
224     queryParams.put(
225       INameList.AN_ISRESTRICTED, new Boolean(true).toString() );
226     queryParams.put(
227       INameList.AN_GROUP, new Integer(group).toString() );
228     
229     // Form the query string
230     boolean isFirst = true;
231     Iterator keys = queryParams.keySet().iterator();
232     while ( keys.hasNext() ) {
233 
234       if ( isFirst ) {
235         isFirst = false;
236       }
237       else {
238         sb.append( "&" );
239       }
240 
241       String key = (String) keys.next();
242       Object value = queryParams.get( key );
243       if ( value instanceof String ) {
244         sb.append( key + "=" + value );
245       }
246       else {
247         String[] values = (String[]) value;
248         for ( int i=0; i<values.length; i++ ) {
249           if ( i > 0 ) {
250             sb.append( "&" );
251           }
252           sb.append( key + "=" + values[i] );
253         } // for String[]
254       } // else String[]
255 
256     } // while keys
257 
258     return sb.toString();
259   } // createQueryString(int,Hashtable)
260 
261   /** Create a link from the specified page */
262   protected String createLink( int group,
263     String contextPath, String page ) throws JspException {
264 
265     // Preconditions
266     if ( contextPath == null ) {
267       throw new IllegalArgumentException( "null contextPath" );
268     }
269     if ( page == null ) {
270       throw new IllegalArgumentException( "null page" );
271     }
272 
273     StringBuffer sb = new StringBuffer( contextPath );
274     sb.append(page);
275 
276     Hashtable queryParams;
277     String tmp = sb.toString();
278     int idx = tmp.indexOf("?");
279     if ( idx > -1 && idx < page.length()-1 ) {
280       String s = tmp.substring( idx+1 );
281       queryParams = HttpUtils.parseQueryString(s);
282     }
283     else {
284       queryParams = new Hashtable();
285     }
286     String queryString = createQueryString( group, queryParams );
287 
288     String url;
289     if ( idx < 0 ) {
290       url = tmp + "?";
291     }
292     else {
293       url = sb.substring( 0, idx );
294     }
295     url = url + queryString;
296 
297     return url;
298   } // createLink(int,String,String)
299 
300   /** Creates a link from the currentGroup request */
301   protected String createLink( int group, HttpServletRequest request ) {
302 
303     StringBuffer url = HttpUtils.getRequestURL( request );
304 
305     String s = request.getQueryString();
306     Hashtable queryParams;
307     if ( s != null ) {
308       queryParams = HttpUtils.parseQueryString(s);
309     }
310     else {
311       queryParams = new Hashtable();
312     }
313 
314     String queryString = createQueryString( group, queryParams );
315     url.append( queryString );
316 
317     return url.toString();
318   } // createLink(int,HttpServletRequest)
319 
320   protected void doStartLink( int group ) throws JspException {
321 
322     // Create a link
323     HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
324     String url = null;
325     if ( this.page != null ) {
326       // Use the specified page
327       String contextPath = request.getContextPath();
328       url = createLink( group, contextPath, page );
329     }
330     else {
331       // Link back to the currentGroup page by default
332       url = createLink( group, request );
333     }
334 
335     // Generate the hyperlink start element
336     HttpServletResponse response =
337       (HttpServletResponse) pageContext.getResponse();
338     StringBuffer results = new StringBuffer("<a href=\"");
339     results.append( response.encodeURL(url) );
340     results.append("\">");
341 
342     // Print this element to our output writer
343     JspWriter writer = pageContext.getOut();
344     try {
345       writer.print(results.toString());
346     } catch (IOException e) {
347       throw new JspException
348           (messages.getMessage("nameselector.io", e.toString()));
349     }
350 
351     return;
352   } // doStartLink(int)
353 
354   protected void doEndLink() throws JspException {
355 
356     // Print the ending element to our output writer
357     JspWriter writer = pageContext.getOut();
358     try {
359       writer.print("</a>");
360     } catch (IOException e) {
361       throw new JspException
362           (messages.getMessage("nameselector.io", e.toString()));
363     }
364 
365     return;
366   } // doEndLink()
367 
368   /** Writes a Integer-based group (2 - 9) as user-friendly text */
369   protected void doGroupText( int group ) throws JspException {
370 
371     if ( group < 2 || group > 9 ) {
372       throw new IllegalArgumentException( "bad index == " + group );
373     }
374 
375     JspWriter writer = pageContext.getOut();
376     try {
377       String lbl = (String) groups().get( new Integer(group) );
378       if ( lbl == null ) {
379         throw new IllegalStateException( "null label for " + group );
380       }
381       writer.print( lbl );
382     } catch (IOException e) {
383       throw new JspException(
384         messages.getMessage("nameselector.io", e.toString()) );
385     }
386 
387     return;
388   } // doGroupText(int)
389 
390   /** Writes the text that separates group links */
391   protected void doGroupLeadingSeparationText(int unused) throws JspException{
392 
393     JspWriter writer = pageContext.getOut();
394     try {
395       writer.print( "&nbsp;" );
396     } catch (IOException e) {
397       throw new JspException(
398         messages.getMessage("nameselector.io", e.toString()) );
399     }
400 
401     return;
402   } // doGroupLeadingSeparationText(int)
403 
404   /** Writes the text that separates group links */
405   protected void doGroupTrailingSeparationText(int unused) throws JspException{
406 
407     JspWriter writer = pageContext.getOut();
408     try {
409       writer.print( "&nbsp;" );
410     } catch (IOException e) {
411       throw new JspException(
412         messages.getMessage("nameselector.io", e.toString()) );
413     }
414 
415     return;
416   } // doGroupTrailingSeparationText(int)
417 
418   /** Write a group link */
419   protected void doGroupLink( int group ) throws JspException {
420 
421     doGroupLeadingSeparationText( group );
422     if ( currentGroup == null ) {
423       doStartLink( group );
424     }
425     else if ( currentGroup != null && group != currentGroup.intValue() ) {
426       doStartLink( group );
427     }
428     doGroupText( group );
429     if ( currentGroup == null ) {
430       doEndLink();
431     }
432     else if ( currentGroup != null && group != currentGroup.intValue() ) {
433       doEndLink();
434     }
435     doGroupTrailingSeparationText( group );
436 
437     return;
438   } // doGroupLink(int)
439 
440   /** Writes an alphabet's worth of group links */
441   protected void doGroupLinks() throws JspException {
442 
443     for ( int group=2; group<10; group++ ) {
444       doGroupLink( group );
445     }
446 
447     return;
448   } // doGroupLinks()
449 
450   /** Render the beginning of the selector */
451   public int doStartTag() throws JspException {
452     return (EVAL_BODY_INCLUDE);
453   }
454 
455   /** Render the end of the selector */
456   public int doEndTag() throws JspException {
457     doGroupLinks();
458     return (EVAL_PAGE);
459   }
460 
461   /**
462    * Release any acquired resources.
463    */
464   public void release() {
465     super.release();
466     this.page = null;
467     return;
468   }
469 
470 } // NameSelector
471 
472 /*
473  * $Log: MemberNameFormatSelectorTag.java,v $
474  * Revision 1.3  2003/02/26 03:38:46  rphall
475  * Added copyright and GPL license
476  *
477  * Revision 1.2  2002/02/18 18:06:22  rphall
478  * Ran dos2unix to remove ^M (carriage return) from end of lines
479  *
480  * Revision 1.1.1.1  2002/01/03 21:57:28  rphall
481  * Initial load, 5th try, Jan-03-2002 4:57 PM
482  *
483  * Revision 1.1  2002/01/01 18:54:07  rphall
484  * Selects first or last name
485  *
486  */
487