View Javadoc

1   package org.appfuse.webapp.taglib;
2   
3   import org.appfuse.model.LabelValue;
4   import org.displaytag.tags.el.ExpressionEvaluator;
5   
6   import javax.servlet.jsp.JspException;
7   import javax.servlet.jsp.tagext.TagSupport;
8   import java.io.IOException;
9   import java.text.Collator;
10  import java.util.ArrayList;
11  import java.util.Collections;
12  import java.util.Comparator;
13  import java.util.List;
14  import java.util.Locale;
15  
16  /**
17   * Tag for creating multiple <select> options for displaying a list of
18   * country names.
19   *
20   * <p>
21   * <b>NOTE</b> - This tag requires a Java2 (JDK 1.2 or later) platform.
22   * </p>
23   *
24   * @author Jens Fischer, Matt Raible
25   * @version $Revision: 1.4.2.1 $ $Date: 2006-06-10 08:00:48 -0600 (Sat, 10 Jun 2006) $
26   */
27  public class CountryTag extends TagSupport {
28      private static final long serialVersionUID = 3905528206810167095L;
29      private String name;
30      private String prompt;
31      private String scope;
32      private String selected;
33  
34      public void setName(String name) {
35          this.name = name;
36      }
37  
38      public void setPrompt(String prompt) {
39          this.prompt = prompt;
40      }
41  
42      public void setDefault(String selected) {
43          this.selected = selected;
44      }
45  
46      public void setToScope(String scope) {
47          this.scope = scope;
48      }
49  
50      /**
51       * Process the start of this tag.
52       *
53       * @return int status
54       * @exception JspException if a JSP exception has occurred
55       * @see javax.servlet.jsp.tagext.Tag#doStartTag()
56       */
57      public int doStartTag() throws JspException {
58          ExpressionEvaluator eval = new ExpressionEvaluator(this, pageContext);
59  
60          if (selected != null) {
61              selected = eval.evalString("default", selected);
62          }
63  
64          Locale userLocale = pageContext.getRequest().getLocale();
65          List countries = this.buildCountryList(userLocale);
66  
67          if (scope != null) {
68              if (scope.equals("page")) {
69                  pageContext.setAttribute(name, countries);
70              } else if (scope.equals("request")) {
71                  pageContext.getRequest().setAttribute(name, countries);
72              } else if (scope.equals("session")) {
73                  pageContext.getSession().setAttribute(name, countries);
74              } else if (scope.equals("application")) {
75                  pageContext.getServletContext().setAttribute(name, countries);
76              } else {
77                  throw new JspException("Attribute 'scope' must be: page, request, session or application");
78              }
79          } else {
80              StringBuilder sb = new StringBuilder();
81              sb.append("<select name=\"").append(name).append("\" id=\"").append(name).append("\" class=\"form-control\">\n");
82  
83              if (prompt != null) {
84                  sb.append("    <option value=\"\" selected=\"selected\">");
85                  sb.append(eval.evalString("prompt", prompt)).append("</option>\n");
86              }
87  
88              for (Object country1 : countries) {
89                  LabelValue country = (LabelValue) country1;
90                  sb.append("    <option value=\"").append(country.getValue()).append("\"");
91  
92                  if ((selected != null) && selected.equals(country.getValue())) {
93                      sb.append(" selected=\"selected\"");
94                  }
95  
96                  sb.append(">").append(country.getLabel()).append("</option>\n");
97              }
98  
99              sb.append("</select>");
100 
101             try {
102                 pageContext.getOut().write(sb.toString());
103             } catch (IOException io) {
104                 throw new JspException(io);
105             }
106         }
107 
108         return super.doStartTag();
109     }
110 
111     // /**
112     // * Release aquired resources to enable tag reusage.
113     // *
114     // * @see javax.servlet.jsp.tagext.Tag#release()
115     // */
116     // public void release() {
117     // super.release();
118     // }
119 
120     /**
121      * Build a List of LabelValues for all the available countries. Uses
122      * the two letter uppercase ISO name of the country as the value and the
123      * localized country name as the label.
124      *
125      * @param locale The Locale used to localize the country names.
126      *
127      * @return List of LabelValues for all available countries.
128      */
129     @SuppressWarnings("unchecked")
130     protected List<LabelValue> buildCountryList(Locale locale) {
131         final Locale[] available = Locale.getAvailableLocales();
132 
133         List<LabelValue> countries = new ArrayList<LabelValue>();
134 
135         for (Locale anAvailable : available) {
136             final String iso = anAvailable.getCountry();
137             final String name = anAvailable.getDisplayCountry(locale);
138 
139             if (!"".equals(iso) && !"".equals(name)) {
140                 LabelValue country = new LabelValue(name, iso);
141 
142                 if (!countries.contains(country)) {
143                     countries.add(new LabelValue(name, iso));
144                 }
145             }
146         }
147 
148         Collections.sort(countries, new LabelValueComparator(locale));
149 
150         return countries;
151     }
152 
153     /**
154      * Class to compare LabelValues using their labels with
155      * locale-sensitive behaviour.
156      */
157     public class LabelValueComparator implements Comparator {
158         private Comparator c;
159 
160         /**
161          * Creates a new LabelValueComparator object.
162          *
163          * @param locale The Locale used for localized String comparison.
164          */
165         public LabelValueComparator(final Locale locale) {
166             c = Collator.getInstance(locale);
167         }
168 
169         /**
170          * Compares the localized labels of two LabelValues.
171          *
172          * @param o1 The first LabelValue to compare.
173          * @param o2 The second LabelValue to compare.
174          *
175          * @return The value returned by comparing the localized labels.
176          */
177         @SuppressWarnings("unchecked")
178         public final int compare(Object o1, Object o2) {
179             LabelValue lhs = (LabelValue) o1;
180             LabelValue rhs = (LabelValue) o2;
181 
182             return c.compare(lhs.getLabel(), rhs.getLabel());
183         }
184     }
185 }