/*
* Copyright 2004, 2005, 2006 Odysseus Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.odysseus.calyxo.forms.taglib.html;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import de.odysseus.calyxo.base.I18nSupport;
import de.odysseus.calyxo.base.conf.ConfigException;
import de.odysseus.calyxo.base.taglib.html.BasicTag;
import de.odysseus.calyxo.forms.view.GroupModel;
import de.odysseus.calyxo.forms.view.ListModel;
/**
* The options tag renders to a sequence of HTML option tags,
* whose attributes are determined by the model of the enclosing select tag.
*
* @author Oliver Stuhr
* @author Christoph Beck
*/
public class ListOptionsTag extends BasicTag {
private SelectTag selectTag;
private String sort;
private String disabled;
private Object selection;
private String key;
private Set keys;
/**
* Default constructor
*/
public ListOptionsTag() {
super(null, true);
}
/*
* (non-Javadoc)
* @see de.odysseus.calyxo.base.taglib.html.AbstractTag#init()
*/
protected void init() throws Exception {
super.init();
selectTag = (SelectTag)findAncestor(SelectTag.class);
if (selectTag == null) {
throw new ConfigException("A listoptions tag must be nested in a select tag!");
}
if (selectTag.getListModel() == null) {
throw new ConfigException("A listoptions tag requires a listModel in select tag '" + selectTag.getName() + "'!");
}
if (selection != null && !selectTag.getGroupModel().isSelectionAvailable()) {
if (selection instanceof String) {
key = (String)selection;
if (!selectTag.isSelectable(key)) {
throw new ConfigException("A selected list option for select '" + selectTag.getName() + "' contains invalid value '" + key + "'!");
}
} else if (selection instanceof String[]) {
String[] strings = (String[])selection;
if (!selectTag.getGroupModel().isMultiple() && strings.length > 1) {
throw new ConfigException("A single selection must be of size <= 1 in '" + selectTag.getName() + "'!");
}
keys = new HashSet(strings.length);
for (int i = 0; i < strings.length; i++) {
if (!selectTag.isSelectable(strings[i])) {
throw new ConfigException("A selected list option for select '" + selectTag.getName() + "' contains invalid value '" + strings[i] + "'!");
}
keys.add(strings[i]);
}
} else {
throw new ConfigException("Unsupported object type in selection: " + keys.getClass() + " (must be String or String[])");
}
}
}
protected int getListModelOrder() {
if (sort == null)
return ListModel.INDEX_ORDER;
String order = sort;
if (order.startsWith("-") || order.startsWith("+"))
order = order.substring(1);
return
order.equals("index") ? ListModel.INDEX_ORDER :
order.equals("key") ? ListModel.KEY_ORDER :
order.equals("value") ? ListModel.VALUE_ORDER :
order.equals("label") ? ListModel.LABEL_ORDER : -1;
}
/*
* (non-Javadoc)
* @see de.odysseus.calyxo.base.taglib.html.AbstractTag#getBodyContent()
*/
public String getBodyContent() throws Exception {
ListModel listModel = selectTag.getListModel();
GroupModel groupModel = selectTag.getGroupModel();
int order = getListModelOrder();
boolean descend = sort.startsWith("-");
Locale locale = I18nSupport.getInstance(pageContext).getLocale(pageContext);
Iterator values = listModel.getValues(order, descend, locale);
StringBuffer s = new StringBuffer();
while (values.hasNext()) {
Object value = values.next();
String key = listModel.getKey(value);
s.append("<option");
s.append(" value=\"");
s.append(key);
s.append("\"");
if (groupModel.isSelected(key)) {
s.append(" selected=\"selected\"");
} else if (!groupModel.isSelectionAvailable()) {
if (key.equals(this.key) || keys != null && keys.contains(key)) {
s.append(" selected=\"selected\"");
}
}
appendAttributes(s);
s.append(">");
s.append(listModel.getLabel(value, locale));
s.append("</option>");
}
return s.toString();
}
/**
* Reset tag attributes
*/
protected void reset() {
super.reset();
sort = null;
selectTag = null;
disabled = null;
selection = null;
key = null;
keys = null;
}
/*
* (non-Javadoc)
* @see de.odysseus.calyxo.base.taglib.html.AbstractTag#appendAttributes(java.lang.StringBuffer)
*/
protected void appendAttributes(StringBuffer buffer) throws Exception {
super.appendAttributes(buffer);
append(buffer, "disabled", getDisabledAttribute());
}
/**
* Get disabled attribute
*/
protected String getDisabledAttribute() {
return disabled == null ? null : "disabled";
}
/**
* Get sort property
*/
public final String getSort() {
return sort;
}
/**
* Set sort property
*
* @param string
*/
public final void setSort(String string) {
sort = string;
}
/**
* Get disabled property
*/
public String getDisabled() {
return disabled;
}
/**
* Set disabled property
*/
public void setDisabled(String string) {
disabled = string;
}
/**
* Get selection property
*/
public Object getSelection() {
return selection;
}
/**
* Set selection property
*/
public void setSelection(Object value) {
selection = value;
}
}