package org.aplikator.server.descriptor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.aplikator.client.shared.data.ListItem;
import org.aplikator.server.data.Context;
import org.aplikator.server.data.QueryBuilder;
import org.aplikator.server.data.Record;
/**
* Implementation of the {@link ListProvider} interface dynamically backed by an Entity
*/
public class EntityListProvider extends ListProvider.Default {
private static final String DEFAULT_LANG = "default";
private View view;
private Property valueProperty;
private Map<String, Property> localeProperties = new HashMap<String, Property>();
private Map<String, List<ListItem>> listValues = new HashMap<String, List<ListItem>>();
;
/**
* @param listName unique identifier of the list
* @param view {@link View} for the {@link Entity} that provides the values for this list.
* The View must contain all Properties used as {@link #valueProperty}
* and {@link #addLanguageProperty(String, Property)}
* @param valueProperty The property (declared in the {@link #view} that contains the values
* that should be returned by the ListItems {@link ListItem#getValue()} method
*/
public EntityListProvider(String listName, View view, Property valueProperty) {
this(listName, view, valueProperty, valueProperty);
}
public EntityListProvider(String listName, View view, Property valueProperty, Property defaultLocaleProperty) {
super(listName);
this.view = view;
this.valueProperty = valueProperty;
addLanguageProperty(DEFAULT_LANG, defaultLocaleProperty);
}
/**
* Calling this method tells the EntityListProvider which property from the backing View should provide ListItem names
* (localized labels) for the given locale
*
* @param lang language code of the locale
* @param property Property containing the names for the given locale
* @return this object for fluent method call chaining
*/
public EntityListProvider addLanguageProperty(String lang, Property property) {
localeProperties.put(lang, property);
listValues.put(lang, new ArrayList<ListItem>());
return this;
}
/**
* @param ctx
*/
@SuppressWarnings("unchecked")
public void refreshListValues(Context ctx) {
for (String loc : listValues.keySet()) {
listValues.get(loc).clear();
}
QueryBuilder qb = ctx.getRecords(view);
if (view.getQueryDescriptors().size() > 0) {
String queryID = view.getQueryDescriptors().get(0).getId();
qb.withQuery(view.getQueryDescriptor(queryID).getQueryExpression(null, ctx));
}
if (view.getSortDescriptors().size() > 0) {
qb.withSort(view.getSortDescriptors().get(0).getItems().toArray(new SortItem[]{}));
}
List<Record> records = qb.list();
for (Record record : records) {
for (String loc : listValues.keySet()) {
ListItem listItem = new ListItem.Default(record.getValue(valueProperty), record.getStringValue(localeProperties.get(loc), ctx));
listValues.get(loc).add(listItem);
}
}
}
@Override
public List<ListItem> getListValues(Context ctx) {
String lang = ctx.getUserLocale().getLanguage();
List<ListItem> list = listValues.get(lang);
if (list == null) {
list = listValues.get(DEFAULT_LANG);
lang = DEFAULT_LANG;
}
if (list.size() == 0) {
refreshListValues(ctx);
list = listValues.get(lang);
}
if (sortByName) {
Collections.sort(list, new ListItem.Comparator());
}
return list;
}
}