/*
* 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.misc;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import de.odysseus.calyxo.base.I18nSupport;
import de.odysseus.calyxo.base.ModuleContext;
import de.odysseus.calyxo.base.access.AccessException;
import de.odysseus.calyxo.base.access.DynamicMapAccessor;
import de.odysseus.calyxo.base.util.MapFacade;
import de.odysseus.calyxo.forms.view.ListModel;
/**
* Use like
* <code>${calyxo.forms.list[mymodel].label[value]}</code>,
* <code>...key[value]</code>,
* <code>...value[key]</code>,
* <code>...values</code>,
* <code>...values['label'].</code>.
*
* @author Christoph Beck
*/
public class ListModelAccessor extends DynamicMapAccessor {
/**
* List model values.
* TODO: This class implements Iterator and Map interfaces.
* That is, this object could be used as an iterator in a forEach tag.
* However, the JSTL specification leaves open, in which order supported
* collection types are applied. If a JSTL forEach tag handler would
* treat this object as a Map, iteration would be over map entries instead!
* Therefore, using items="${...list.values}" seems to be ambigous and is
* discouraged... Use items="${...list.values['index']}" instead.
* A solution would be to <strong>not</strong> let <code>MapFacade</code>
* implement <code>Map</code>.
*/
public static class ListModelValues extends MapFacade implements Iterator {
private ListModel model;
private Locale locale;
private Iterator delegate;
ListModelValues(ListModel model, Locale locale) {
this.model = model;
this.locale = locale;
}
/* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
if (delegate == null) {
delegate = model.getValues();
}
return delegate.hasNext();
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next() {
if (delegate == null) {
delegate = model.getValues();
}
return delegate.next();
}
/* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
public void remove() {
if (delegate == null) {
delegate = model.getValues();
}
delegate.remove();
}
/**
* Use sort criteria [+-]?(index|key|value|label)
*/
public Object get(Object key) {
String criteria = (String)key;
boolean desc = criteria.startsWith("-");
int order = ListModel.INDEX_ORDER;
if (criteria.endsWith("value")) {
order = ListModel.VALUE_ORDER;
} else if (criteria.endsWith("key")) {
order = ListModel.KEY_ORDER;
} else if (criteria.endsWith("label")) {
order = ListModel.LABEL_ORDER;
}
// delegate = model.getValues(order, desc, locale);
// return this;
return model.getValues(order, desc, locale);
}
}
public static class ListModelBean {
private ListModel model;
private Locale locale;
private Map labelMap;
private Map keyMap;
private Map valueMap;
ListModelBean(ListModel model, Locale locale) {
this.model = model;
this.locale = locale;
}
public Map getValue() {
if (valueMap == null) {
valueMap = new MapFacade() {
public Object get(Object key) {
return model.getValue((String)key);
}
};
}
return valueMap;
}
public Map getLabel() {
if (labelMap == null) {
labelMap = new MapFacade() {
public Object get(Object value) {
return model.getLabel(value, locale);
}
};
}
return labelMap;
}
public Map getKey() {
if (keyMap == null) {
keyMap = new MapFacade() {
public Object get(Object value) {
return model.getKey(value);
}
};
}
return keyMap;
}
public Iterator getValues() {
return new ListModelValues(model, locale);
}
}
private I18nSupport i18n;
public ListModelAccessor(ModuleContext context) {
i18n = I18nSupport.getInstance(context);
}
/*
* (non-Javadoc)
* @see de.odysseus.calyxo.base.access.DynamicMapAccessor#get(javax.servlet.http.HttpServletRequest, java.lang.Object)
*/
protected Object get(HttpServletRequest request, Object key) {
ListModel model = (ListModel)key;
if (model == null) {
throw new AccessException("No list model!");
}
return new ListModelBean(model, i18n.getLocale(request));
}
/* (non-Javadoc)
* @see de.odysseus.calyxo.base.access.Accessor#isCacheable()
*/
public boolean isCacheable() {
return true;
}
}