/******************************************************************************* * Gisgraphy Project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA * * Copyright 2008 Gisgraphy project * David Masclet <davidmasclet@gisgraphy.com> * * *******************************************************************************/ package com.gisgraphy.webapp.taglib; import java.io.IOException; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import org.displaytag.tags.el.ExpressionEvaluator; import com.gisgraphy.model.LabelValue; /** * Tag for creating multiple <select> options for displaying a list of * country names. * <p> * <b>NOTE</b> - This tag requires a Java2 (JDK 1.2 or later) platform. * </p> * * @author Jens Fischer, Matt Raible * @version $Revision: 1.4.2.1 $ $Date: 2006-06-10 08:00:48 -0600 (Sat, 10 Jun * 2006) $ */ public class CountryTag extends TagSupport { private static final long serialVersionUID = 3905528206810167095L; private String name; private String prompt; private String scope; private String selected; public void setName(String name) { this.name = name; } public void setPrompt(String prompt) { this.prompt = prompt; } public void setDefault(String selected) { this.selected = selected; } public void setToScope(String scope) { this.scope = scope; } /** * Process the start of this tag. * * @return int status * @exception JspException * if a JSP exception has occurred * @see javax.servlet.jsp.tagext.Tag#doStartTag() */ @Override public int doStartTag() throws JspException { ExpressionEvaluator eval = new ExpressionEvaluator(this, pageContext); if (selected != null) { selected = eval.evalString("default", selected); } Locale userLocale = pageContext.getRequest().getLocale(); List<LabelValue> countries = this.buildCountryList(userLocale); if (scope != null) { if (scope.equals("page")) { pageContext.setAttribute(name, countries); } else if (scope.equals("request")) { pageContext.getRequest().setAttribute(name, countries); } else if (scope.equals("session")) { pageContext.getSession().setAttribute(name, countries); } else if (scope.equals("application")) { pageContext.getServletContext().setAttribute(name, countries); } else { throw new JspException( "Attribute 'scope' must be: page, request, session or application"); } } else { StringBuffer sb = new StringBuffer(); sb.append("<select name=\"").append(name).append("\" id=\"") .append(name).append("\" class=\"select\">\n"); if (prompt != null) { sb.append(" <option value=\"\" selected=\"selected\">"); sb.append(eval.evalString("prompt", prompt)).append( "</option>\n"); } for (Object country1 : countries) { LabelValue country = (LabelValue) country1; sb.append(" <option value=\"").append(country.getValue()) .append("\""); if ((selected != null) && selected.equals(country.getValue())) { sb.append(" selected=\"selected\""); } sb.append(">").append(country.getLabel()).append("</option>\n"); } sb.append("</select>"); try { pageContext.getOut().write(sb.toString()); } catch (IOException io) { throw new JspException(io); } } return super.doStartTag(); } /** * Release aquired resources to enable tag reusage. * * @see javax.servlet.jsp.tagext.Tag#release() */ @Override public void release() { super.release(); } /** * Build a List of LabelValues for all the available countries. Uses the two * letter uppercase ISO name of the country as the value and the localized * country name as the label. * * @param locale * The Locale used to localize the country names. * @return List of LabelValues for all available countries. */ @SuppressWarnings("unchecked") protected List<LabelValue> buildCountryList(Locale locale) { final Locale[] available = Locale.getAvailableLocales(); List<LabelValue> countries = new ArrayList<LabelValue>(); for (Locale anAvailable : available) { final String iso = anAvailable.getCountry(); final String name = anAvailable.getDisplayCountry(locale); if (!"".equals(iso) && !"".equals(name)) { LabelValue country = new LabelValue(name, iso); if (!countries.contains(country)) { countries.add(new LabelValue(name, iso)); } } } Collections.sort(countries, new LabelValueComparator(locale)); return countries; } /** * Class to compare LabelValues using their labels with locale-sensitive * behaviour. */ @SuppressWarnings("unchecked") public class LabelValueComparator implements Comparator { private Comparator c; /** * Creates a new LabelValueComparator object. * * @param locale * The Locale used for localized String comparison. */ public LabelValueComparator(final Locale locale) { c = Collator.getInstance(locale); } /** * Compares the localized labels of two LabelValues. * * @param o1 * The first LabelValue to compare. * @param o2 * The second LabelValue to compare. * @return The value returned by comparing the localized labels. */ @SuppressWarnings("unchecked") public final int compare(Object o1, Object o2) { LabelValue lhs = (LabelValue) o1; LabelValue rhs = (LabelValue) o2; return c.compare(lhs.getLabel(), rhs.getLabel()); } } }