package org.aplikator.server.descriptor;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.aplikator.client.shared.descriptor.EntityDTO;
import org.aplikator.client.shared.descriptor.FormDTO;
import org.aplikator.client.shared.descriptor.ViewDTO;
import org.aplikator.server.data.Context;
import org.aplikator.server.data.PersisterTriggers;
import org.aplikator.server.query.QueryExpression;
import org.aplikator.server.query.QueryParameterReference;
import com.google.common.base.Preconditions;
public class View extends LocalizedServerDescriptorBase {
private static final int DEFAULT_PAGE_SIZE = 15;
public PersisterTriggers trigger;
private List<QueryDescriptor> filters = new ArrayList<QueryDescriptor>();
private List<SortDescriptor> sorts = new ArrayList<SortDescriptor>();
private List<Function> functions = new ArrayList<Function>();
private Entity entity;
private List<Property<? extends Serializable>> properties = new ArrayList<Property<? extends Serializable>>();
private List<Property<? extends Serializable>> tableProperties = new ArrayList<Property<? extends Serializable>>();
private Form form;
private int pageSize = DEFAULT_PAGE_SIZE;
private int listPanelWidth = 3;
private boolean openAsTable = false;
public View(Entity entity) {
this(entity, null);
}
public View(Entity entity, String id) {
this(entity, id, true);
}
public View(Entity entity, String id, boolean addDefaultSorts) {
super(entity.getId().substring(entity.getId().indexOf(TYPE_DELIMITER) + 1) + (id != null ? (SUFFIX_DELIMITER + id) : ""));
this.entity = entity;
this.setLocalizationKey(entity.getLocalizationKey() + (id != null ? ("." + id) : ""));
if (addDefaultSorts) {
addSortDescriptor("id_desc", "newest", SortItem.descending(entity.getPrimaryKey()));
addSortDescriptor("id_asc", "oldest", SortItem.ascending(entity.getPrimaryKey()));
addSortDescriptor("latest_desc", "latest", SortItem.descending(entity.getTimeStamp()));
}
addQueryDescriptor(this.getId().substring(this.getId().indexOf(TYPE_DELIMITER) + 1) + "_searchall", "searchAll", null);
}
public View(View masterView, String id) {
super(masterView.getId().substring(masterView.getId().indexOf(TYPE_DELIMITER) + 1) + SUFFIX_DELIMITER + id);
this.entity = masterView.entity;
this.setLocalizationKey(masterView.getLocalizationKey() + "." + id);
for (QueryDescriptor qd : masterView.filters) {
this.addQueryDescriptor(qd);
}
this.sorts = masterView.sorts;
this.functions = masterView.functions;
this.properties = masterView.properties;
this.tableProperties = masterView.tableProperties;
this.form = masterView.form;
this.pageSize = masterView.pageSize;
this.listPanelWidth = masterView.listPanelWidth;
this.openAsTable = masterView.openAsTable;
}
public List<Property<? extends Serializable>> getProperties() {
return properties;
}
public List<Property<? extends Serializable>> getTableProperties() {
return tableProperties;
}
public View addProperty(Property<? extends Serializable> property) {
if (property.getRefferedThrough() instanceof Collection) {
return addProperty(property, true, false, false);
} else {
return addProperty(property, true, true, true);
}
}
public View addProperty(Property<? extends Serializable> property, boolean forTable, boolean sort, boolean filter) {
Preconditions.checkArgument(property != null, "Attempted to add null property to view: " + this.entity);
properties.add(property);
if (forTable) {
tableProperties.add(property);
}
if (!property.isVirtual()) {
if (sort) {
addSortDescriptor(property.getId().substring(property.getId().indexOf(TYPE_DELIMITER) + 1) + "_asc", property.getLocalizationKey(), SortItem.ascending(property));
addSortDescriptor(property.getId().substring(property.getId().indexOf(TYPE_DELIMITER) + 1) + "_desc", property.getLocalizationKey(), SortItem.descending(property));
}
if (filter) {
addQueryDescriptor(property.getId().substring(property.getId().indexOf(TYPE_DELIMITER) + 1) + "_contains", property.getLocalizationKey(), property.STARTSWITH_IGNORECASE(QueryParameterReference.param(0)), new QueryParameter(property));
}
}
return this;
}
private QueryDescriptor createQueryDescriptor(String queryId, String queryLabel, QueryExpression queryExpression, QueryParameter[] parameters) {
QueryDescriptor queryDescriptor = new QueryDescriptor(this.getId().substring(this.getId().indexOf(TYPE_DELIMITER) + 1) + SUFFIX_DELIMITER + queryId, queryLabel);
queryDescriptor.setQueryExpression(queryExpression);
if (parameters != null) {
for (QueryParameter p : parameters) {
queryDescriptor.addQueryParameter(p);
}
}
return queryDescriptor;
}
public View addQueryDescriptor(String queryId, String queryLabel, QueryExpression queryExpression, QueryParameter... parameters) {
QueryDescriptor queryDescriptor = createQueryDescriptor(queryId, queryLabel, queryExpression, parameters);
filters.add(queryDescriptor);
return this;
}
public View addQueryDescriptor(String queryId, String queryLabel, QueryExpression queryExpression) {
return addQueryDescriptor(queryId, queryLabel, queryExpression, new QueryParameter[]{});
}
public View addQueryDescriptor(QueryDescriptor queryDescriptor) {
filters.add(queryDescriptor);
return this;
}
public View insertQueryDescriptor(String queryId, String queryLabel, QueryExpression queryExpression, QueryParameter... parameters) {
QueryDescriptor queryDescriptor = createQueryDescriptor(queryId, queryLabel, queryExpression, parameters);
filters.add(0, queryDescriptor);
return this;
}
public View insertQueryDescriptor(String queryId, String queryLabel, QueryExpression queryExpression) {
return insertQueryDescriptor(queryId, queryLabel, queryExpression, new QueryParameter[]{});
}
public View insertQueryDescriptor(QueryDescriptor queryDescriptor) {
filters.add(0, queryDescriptor);
return this;
}
List<QueryDescriptor> getQueryDescriptors() {
return filters;
}
public QueryDescriptor getQueryDescriptor(String id) {
if (id == null || "".equals(id)) {
return filters.get(0);
}
for (QueryDescriptor desc : filters) {
if (id.equals(desc.getId()))
return desc;
}
throw new IllegalArgumentException("QueryDescriptor " + id + " not found");
}
public QueryDescriptor getDefaultQueryDescriptor() {
if (filters.size() > 0) {
return filters.get(0);
} else {
return null;
}
}
public View addSortDescriptor(String sortId, String sortLabel, SortItem... items) {
SortDescriptor sd = new SortDescriptor(this.getId().substring(this.getId().indexOf(TYPE_DELIMITER) + 1) + SUFFIX_DELIMITER + sortId, sortLabel);
for (SortItem it : items) {
sd.addItem(it);
}
sorts.add(sd);
return this;
}
public View insertFirstSortDescriptor(String sortId, String sortLabel, SortItem... items) {
SortDescriptor sd = new SortDescriptor(this.getId().substring(this.getId().indexOf(TYPE_DELIMITER) + 1) + SUFFIX_DELIMITER + sortId, sortLabel);
for (SortItem it : items) {
sd.addItem(it);
}
sorts.add(0, sd);
return this;
}
@SafeVarargs
public final View setDefaultSortProperty(Property<? extends Serializable>... properties) {
if (properties.length == 0) {
return this;
}
SortItem[] sortItems = new SortItem[properties.length];
for (int i = 0; i < properties.length; i++) {
sortItems[i] = SortItem.ascending(properties[i]);
}
insertFirstSortDescriptor("default", properties[0].getLocalizationKey(), sortItems);
return this;
}
List<SortDescriptor> getSortDescriptors() {
return sorts;
}
public SortDescriptor getSortDescriptor(String id) {
for (SortDescriptor desc : sorts) {
if (id.equals(desc.getId()))
return desc;
}
throw new IllegalArgumentException("SortDescriptor " + id + " not found");
}
public SortDescriptor getDefaultSortDescriptor() {
if (sorts.size() > 0) {
return sorts.get(0);
} else {
return null;
}
}
public View addFunction(Function function) {
functions.add(function);
return this;
}
List<Function> getFunctions() {
return functions;
}
public Entity getEntity() {
return entity;
}
public int getPageSize() {
return pageSize;
}
public View setPageSize(int pageSize) {
if (pageSize <= 0)
throw new IllegalArgumentException("Page size must be greater than 0");
this.pageSize = pageSize;
return this;
}
public View setListPanelWidth(int listPanelWidth) {
this.listPanelWidth = listPanelWidth;
return this;
}
public View openAsTable() {
this.openAsTable = true;
return this;
}
public ViewDTO getViewDTO(Context ctx) {
ViewDTO viewDTO = new ViewDTO(this.getId(), this.getLocalizedName(ctx), this.getPageSize());
viewDTO.setListPanelWidth(listPanelWidth);
viewDTO.setOpenAsTable(openAsTable);
EntityDTO ent = new EntityDTO(entity.getId(), entity.getLocalizedName(ctx));
ent.setIndexed(entity.isIndexed());
ent.setPrimaryKey(entity.getPrimaryKey().getPropertyDTO(ctx));
viewDTO.setEntity(ent);
for (Property<? extends Serializable> property : getTableProperties()) {
viewDTO.addProperty(property.getPropertyDTO(ctx));
}
for (Function f : this.getFunctions()) {
viewDTO.addFunction(f.getFunctionDTO(ctx));
}
for (SortDescriptor sd : this.getSortDescriptors()) {
viewDTO.addSortDescriptor(sd.getSortDescriptorDTO(ctx));
}
for (QueryDescriptor qd : this.getQueryDescriptors()) {
viewDTO.addQueryDescriptor(qd.getQueryDescriptorDTO(ctx));
}
viewDTO.setFormDescriptor(createFormDescriptor(ctx));
return viewDTO;
}
private FormDTO createFormDescriptor(Context ctx) {
Form f = getForm(ctx);
if (f == null) {
throw new IllegalStateException("Form is not defined for view " + this.getId());
}
FormDTO retval = new FormDTO(f.getId(), f.getLocalizedName(ctx), f.isHorizontal());
retval.setLayout(f.getLayout().getWidgetDescriptor(ctx));
return retval;
}
public PersisterTriggers getPersisterTriggers() {
if (trigger == null) {
return getEntity().getPersisterTriggers();
} else {
return this.trigger;
}
}
public View setPersistersTriggers(PersisterTriggers triggers) {
this.trigger = triggers;
return this;
}
public Form getForm(Context context) {
return form;
}
public View setForm(Form form) {
this.form = form;
return this;
}
public View form(Widget layout, boolean horizontal) {
return setForm(Form.form(layout, horizontal));
}
public View form(Widget layout) {
return form(layout, true);
}
@Override
public AccessControl getAccessControl() {
AccessControl retval = super.getAccessControl();
if (retval == null) {
retval = entity.getAccessControl();
}
return retval;
}
/*public void registerClientProperty(String name, Object obj) {
this.clientProperties.put(name, obj);
}
public void deregisterClientProperty(String name) {
this.clientProperties.remove(name);
}
public Set<String> getClientPropertiesKeys() {
return this.clientProperties.keySet();
}
public Object getClientProperty(String name) {
return this.clientProperties.get(name);
}*/
}