/**
* ***************************************************************************
* Copyright (c) 2010 Qcadoo Limited
* Project: Qcadoo Framework
* Version: 1.4
*
* This file is part of Qcadoo.
*
* Qcadoo is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation; either version 3 of the License,
* or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ***************************************************************************
*/
package com.qcadoo.view.internal.components.grid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.qcadoo.model.api.DataDefinition;
import com.qcadoo.model.api.Entity;
import com.qcadoo.model.api.EntityOpResult;
import com.qcadoo.model.api.FieldDefinition;
import com.qcadoo.model.api.search.CustomRestriction;
import com.qcadoo.model.api.search.JoinType;
import com.qcadoo.model.api.search.SearchCriteriaBuilder;
import com.qcadoo.model.api.search.SearchOrders;
import com.qcadoo.model.api.search.SearchRestrictions;
import com.qcadoo.model.api.search.SearchResult;
import com.qcadoo.model.api.types.BelongsToType;
import com.qcadoo.model.api.types.FieldType;
import com.qcadoo.model.api.types.JoinFieldHolder;
import com.qcadoo.model.api.types.ManyToManyType;
import com.qcadoo.model.api.validators.ErrorMessage;
import com.qcadoo.model.internal.ProxyEntity;
import com.qcadoo.model.internal.types.EnumType;
import com.qcadoo.security.api.SecurityRole;
import com.qcadoo.security.api.SecurityRolesService;
import com.qcadoo.view.api.components.GridComponent;
import com.qcadoo.view.api.components.grid.GridComponentMultiSearchFilter;
import com.qcadoo.view.api.components.lookup.FilterValueHolder;
import com.qcadoo.view.internal.CriteriaModifier;
import com.qcadoo.view.internal.FilterValueHolderImpl;
import com.qcadoo.view.internal.RowStyleResolver;
import com.qcadoo.view.internal.states.AbstractComponentState;
public final class GridComponentState extends AbstractComponentState implements GridComponent {
enum ExportMode {
ALL, SELECTED
};
public static final String JSON_SELECTED_ENTITY_ID = "selectedEntityId";
public static final String JSON_HEADER_VALUE = "headerValue";
public static final String JSON_BELONGS_TO_ENTITY_ID = "belongsToEntityId";
public static final String JSON_FIRST_ENTITY = "firstEntity";
public static final String JSON_MAX_ENTITIES = "maxEntities";
public static final String JSON_TOTAL_ENTITIES = "totalEntities";
public static final String JSON_ORDER = "order";
public static final String JSON_ONLY_ACTIVE = "onlyActive";
public static final String JSON_ONLY_INACTIVE = "onlyInactive";
public static final String JSON_ORDER_COLUMN = "column";
public static final String JSON_ORDER_DIRECTION = "direction";
public static final String JSON_FILTERS = "filters";
public static final String JSON_FILTERS_ENABLED = "filtersEnabled";
public static final String JSON_MULTI_SEARCH_FILTER = "multiSearchFilter";
public static final String JSON_MULTI_SEARCH_ENABLED = "multiSearchEnabled";
public static final String JSON_ENTITIES = "entities";
public static final String JSON_EDITABLE = "isEditable";
public static final String JSON_MULTISELECT_MODE = "multiselectMode";
public static final String JSON_SELECTED_ENTITIES = "selectedEntities";
public static final String JSON_ENTITIES_TO_MARK_AS_NEW = "entitiesToMarkAsNew";
public static final String JSON_ENTITIES_TO_MARK_WITH_CSS_CLASS = "entitiesToMarkWithCssClass";
public static final String JSON_CRITERIA_MODIFIER_PARAMETER = "criteriaModifierParameter";
public static final String JSON_DELETE_ENABLED = "deleteEnabled";
public static final String JSON_AUTOMATIC_REFRESH = "autoRefresh";
private final GridEventPerformer eventPerformer = new GridEventPerformer();
private final Map<String, GridComponentColumn> columns;
private final FieldDefinition belongsToFieldDefinition;
private Long selectedEntityId;
private Long belongsToEntityId;
private List<Entity> entities;
private int totalEntities;
private int firstResult;
private int maxResults = Integer.MAX_VALUE;
private boolean filtersEnabled = true;
private boolean multiSearchEnabled = false;
private final List<GridComponentOrderColumn> orderColumns = new LinkedList<GridComponentOrderColumn>();
private boolean multiselectMode = false;
private Boolean isEditable = null;
private Set<Long> selectedEntities = new HashSet<Long>();
private Set<Long> entitiesToMarkAsNew = new HashSet<Long>();
private CustomRestriction customRestriction;
private final Map<String, String> filters = new HashMap<String, String>();
private final GridComponentMultiSearchFilter multiSearchFilter = new GridComponentMultiSearchFilter();
private final PredefinedFilter defaultPredefinedFilter;
private boolean onlyActive = true;
private boolean onlyInactive = false;
private final boolean activable;
private boolean deletable = false;
private final boolean weakRelation;
private final DataDefinition scopeFieldDataDefinition;
private final RowStyleResolver rowStyleResolver;
private final CriteriaModifier criteriaModifier;
private final FilterValueHolder criteriaModifierParameter;
private final SecurityRole authorizationRole;
private String deletableAuthorizationRole = "";
private boolean deleteEnabled = false;
private final SecurityRolesService securityRolesService;
private boolean useDto = false;
private boolean footerRow = false;
private String columnsToSummary = "";
private String columnsToSummaryTime = "";
private boolean autoRefresh = false;
private final GridComponentPattern pattern;
public GridComponentState(final DataDefinition dataDefinition, final GridComponentPattern pattern) {
super(pattern);
this.pattern = pattern;
this.belongsToFieldDefinition = pattern.getBelongsToFieldDefinition();
if (pattern.getDefaultOrderColumn() != null) {
this.orderColumns.add(new GridComponentOrderColumn(pattern.getDefaultOrderColumn(), pattern
.getDefaultOrderDirection()));
}
this.activable = pattern.isActivable();
this.onlyActive = pattern.isOnlyActive();
this.weakRelation = pattern.isWeakRelation();
this.scopeFieldDataDefinition = dataDefinition;
this.rowStyleResolver = pattern.getRowStyleResolver();
this.criteriaModifier = pattern.getCriteriaModifier();
this.criteriaModifierParameter = new FilterValueHolderImpl();
this.defaultPredefinedFilter = pattern.getDefaultPredefinedFilter();
this.authorizationRole = pattern.getAuthorizationRole();
this.securityRolesService = pattern.getApplicationContext().getBean(SecurityRolesService.class);
this.deletable = pattern.isDeletable();
this.deletableAuthorizationRole = pattern.getDeletableAuthorizationRole();
this.autoRefresh = pattern.isautoRefresh();
this.footerRow = pattern.isFooterRow();
this.columnsToSummary = pattern.getColumnsToSummary();
this.columnsToSummaryTime = pattern.getColumnsToSummaryTime();
this.useDto = pattern.isUseDto();
this.columns = pattern.getColumns();
registerEvent("refresh", eventPerformer, "refresh");
registerEvent("select", eventPerformer, "selectEntity");
registerEvent("addExistingEntity", eventPerformer, "addExistingEntity");
registerEvent("remove", eventPerformer, "removeSelectedEntity");
registerEvent("moveUp", eventPerformer, "moveUpSelectedEntity");
registerEvent("moveDown", eventPerformer, "moveDownSelectedEntity");
registerEvent("copy", eventPerformer, "copySelectedEntity");
registerEvent("activate", eventPerformer, "activateSelectedEntity");
registerEvent("deactivate", eventPerformer, "deactivateSelectedEntity");
}
@Override
@SuppressWarnings("unchecked")
protected void initializeContext(final JSONObject json) throws JSONException {
super.initializeContext(json);
Iterator<String> iterator = json.keys();
while (iterator.hasNext()) {
String field = iterator.next();
if (JSON_BELONGS_TO_ENTITY_ID.equals(field)) {
onScopeEntityIdChange(json.getLong(field));
} else if (JSON_COMPONENT_OPTIONS.equals(field)) {
JSONObject jsonOptions = json.getJSONObject(JSON_COMPONENT_OPTIONS);
passFiltersFromJson(jsonOptions);
passMultiSearchFilterFromJson(jsonOptions);
passSelectedEntityIdFromJson(jsonOptions);
passSelectedEntitiesFromJson(jsonOptions);
passEntitiesFromJson(jsonOptions);
passCriteriaModifierParameterFromJson(jsonOptions);
}
}
}
@Override
protected void initializeContent(final JSONObject json) throws JSONException {
if (json.has(JSON_SELECTED_ENTITY_ID) && !json.isNull(JSON_SELECTED_ENTITY_ID)) {
selectedEntityId = json.getLong(JSON_SELECTED_ENTITY_ID);
}
if (json.has(JSON_MULTISELECT_MODE) && !json.isNull(JSON_MULTISELECT_MODE)) {
multiselectMode = json.getBoolean(JSON_MULTISELECT_MODE);
}
if (json.has(JSON_SELECTED_ENTITIES) && !json.isNull(JSON_SELECTED_ENTITIES)) {
JSONObject selectedEntitiesObj = json.getJSONObject(JSON_SELECTED_ENTITIES);
JSONArray selectedEntitiesIds = selectedEntitiesObj.names();
for (int i = 0; selectedEntitiesIds != null && i < selectedEntitiesIds.length(); i++) {
String key = selectedEntitiesIds.getString(i);
boolean isSelected = false;
if (selectedEntitiesObj.has(key) && !selectedEntitiesObj.isNull(key)) {
isSelected = selectedEntitiesObj.getBoolean(key);
}
if (isSelected) {
selectedEntities.add(Long.parseLong(key));
}
}
}
if (json.has(JSON_BELONGS_TO_ENTITY_ID) && !json.isNull(JSON_BELONGS_TO_ENTITY_ID)) {
belongsToEntityId = json.getLong(JSON_BELONGS_TO_ENTITY_ID);
}
if (json.has(JSON_FIRST_ENTITY) && !json.isNull(JSON_FIRST_ENTITY)) {
firstResult = json.getInt(JSON_FIRST_ENTITY);
}
if (json.has(JSON_MAX_ENTITIES) && !json.isNull(JSON_MAX_ENTITIES)) {
maxResults = json.getInt(JSON_MAX_ENTITIES);
}
if (json.has(JSON_ONLY_ACTIVE) && !json.isNull(JSON_ONLY_ACTIVE) && activable) {
onlyActive = json.getBoolean(JSON_ONLY_ACTIVE);
}
if (json.has(JSON_ONLY_INACTIVE) && !json.isNull(JSON_ONLY_INACTIVE) && activable) {
onlyInactive = json.getBoolean(JSON_ONLY_INACTIVE);
}
if (json.has(JSON_ORDER)) {
JSONArray orderJson = json.getJSONArray(JSON_ORDER);
orderColumns.clear();
for (int i = 0; i < orderJson.length(); i++) {
JSONObject orderColumn = orderJson.getJSONObject(i);
if (orderColumn.has(JSON_ORDER_COLUMN) && orderColumn.has(JSON_ORDER_DIRECTION)) {
orderColumns.add(new GridComponentOrderColumn(orderColumn.getString(JSON_ORDER_COLUMN), orderColumn
.getString(JSON_ORDER_DIRECTION)));
}
}
}
if (json.has(JSON_AUTOMATIC_REFRESH)) {
autoRefresh = json.getBoolean(JSON_AUTOMATIC_REFRESH);
}
if ((belongsToFieldDefinition != null && belongsToEntityId == null) || !securityRolesService.canAccess(authorizationRole)) {
setEnabled(false);
}
if (deletable && StringUtils.isNotEmpty(deletableAuthorizationRole)
&& securityRolesService.canAccess(deletableAuthorizationRole) || deletable
&& StringUtils.isEmpty(deletableAuthorizationRole)) {
this.deleteEnabled = true;
}
passFiltersFromJson(json);
passMultiSearchFilterFromJson(json);
requestRender();
requestUpdateState();
}
private void applyPredefinedFilter(final PredefinedFilter predefinedFilter) {
if (predefinedFilter == null) {
return;
}
orderColumns.clear();
if (predefinedFilter.getOrderColumn() != null) {
orderColumns
.add(new GridComponentOrderColumn(predefinedFilter.getOrderColumn(), predefinedFilter.getOrderDirection()));
}
filters.putAll(predefinedFilter.getParsedFilterRestrictions());
}
@SuppressWarnings("unchecked")
private void passFiltersFromJson(final JSONObject json) throws JSONException {
if (json.has(JSON_FILTERS_ENABLED) && !json.isNull(JSON_FILTERS_ENABLED)) {
filtersEnabled = json.getBoolean(JSON_FILTERS_ENABLED);
}
if (json.has(JSON_FILTERS) && !json.isNull(JSON_FILTERS)) {
filtersEnabled = true;
JSONObject filtersJson = json.getJSONObject(JSON_FILTERS);
Iterator<String> filtersKeys = filtersJson.keys();
while (filtersKeys.hasNext()) {
String column = filtersKeys.next();
filters.put(column, filtersJson.getString(column).trim());
}
} else {
applyPredefinedFilter(defaultPredefinedFilter);
}
}
private void passMultiSearchFilterFromJson(final JSONObject json) throws JSONException {
if (json.has(JSON_MULTI_SEARCH_ENABLED) && !json.isNull(JSON_MULTI_SEARCH_ENABLED)) {
multiSearchEnabled = json.getBoolean(JSON_MULTI_SEARCH_ENABLED);
}
if (json.has(JSON_MULTI_SEARCH_FILTER) && !json.isNull(JSON_MULTI_SEARCH_FILTER)) {
multiSearchFilter.clear();
JSONObject jsonMultiSearchFilter = json.getJSONObject(JSON_MULTI_SEARCH_FILTER);
if (jsonMultiSearchFilter.has(GridComponentMultiSearchFilter.JSON_GROUP_OPERATOR_FIELD)
&& !jsonMultiSearchFilter.isNull(GridComponentMultiSearchFilter.JSON_GROUP_OPERATOR_FIELD)) {
multiSearchFilter.setGroupOperator(jsonMultiSearchFilter
.getString(GridComponentMultiSearchFilter.JSON_GROUP_OPERATOR_FIELD));
}
if (jsonMultiSearchFilter.has(GridComponentMultiSearchFilter.JSON_RULES_FIELD)
&& !jsonMultiSearchFilter.isNull(GridComponentMultiSearchFilter.JSON_RULES_FIELD)) {
JSONArray jsonMultiSearchFilterRules = jsonMultiSearchFilter
.getJSONArray(GridComponentMultiSearchFilter.JSON_RULES_FIELD);
for (int i = 0; i < jsonMultiSearchFilterRules.length(); ++i) {
JSONObject jsonRule = jsonMultiSearchFilterRules.getJSONObject(i);
multiSearchFilter.addRule(
jsonRule.getString(GridComponentMultiSearchFilterRule.JSON_FIELD_FIELD),
jsonRule.getString(GridComponentMultiSearchFilterRule.JSON_OPERATOR_FIELD),
jsonRule.isNull(GridComponentMultiSearchFilterRule.JSON_DATA_FIELD) ? null : jsonRule
.getString(GridComponentMultiSearchFilterRule.JSON_DATA_FIELD));
}
}
}
}
private void passSelectedEntitiesFromJson(final JSONObject json) throws JSONException {
if (json.has(JSON_SELECTED_ENTITIES) && !json.isNull(JSON_SELECTED_ENTITIES)) {
selectedEntities = Sets.newHashSet();
JSONArray entitiesToSelect = json.getJSONArray(JSON_SELECTED_ENTITIES);
for (int i = 0; i < entitiesToSelect.length(); i++) {
selectedEntities.add(Long.valueOf(entitiesToSelect.get(i).toString()));
}
}
}
private void passSelectedEntityIdFromJson(final JSONObject json) throws JSONException {
if (json.has(JSON_SELECTED_ENTITY_ID) && !json.isNull(JSON_SELECTED_ENTITY_ID)) {
selectedEntityId = json.getLong(JSON_SELECTED_ENTITY_ID);
}
}
private void passEntitiesFromJson(final JSONObject json) throws JSONException {
if (gridIsEmpty() && json.has(JSON_ENTITIES) && !json.isNull(JSON_ENTITIES)) {
entities = Lists.newArrayList();
JSONArray givenEntities = json.getJSONArray(JSON_ENTITIES);
Long entityId = null;
for (int i = 0; i < givenEntities.length(); i++) {
entityId = Long.valueOf(givenEntities.get(i).toString());
entities.add(getDataDefinition().get(entityId));
}
}
}
private void passCriteriaModifierParameterFromJson(final JSONObject json) throws JSONException {
if (json.has(JSON_CRITERIA_MODIFIER_PARAMETER) && !json.isNull(JSON_CRITERIA_MODIFIER_PARAMETER)) {
criteriaModifierParameter.initialize(json.getJSONObject(JSON_CRITERIA_MODIFIER_PARAMETER));
}
}
private boolean gridIsEmpty() {
return belongsToEntityId == null;
}
@Override
public void onFieldEntityIdChange(final Long entityId) {
setSelectedEntityId(entityId);
}
@Override
public void onScopeEntityIdChange(final Long scopeEntityId) {
if (belongsToFieldDefinition == null) {
throw new IllegalStateException("Grid doesn't have scopeField, it cannot set scopeEntityId");
}
if (belongsToEntityId != null && !belongsToEntityId.equals(scopeEntityId)) {
setSelectedEntityId(null);
selectedEntities = new HashSet<Long>();
multiselectMode = false;
}
belongsToEntityId = scopeEntityId;
setEnabled(scopeEntityId != null && securityRolesService.canAccess(authorizationRole));
}
@Override
protected JSONObject renderContent() throws JSONException {
if (entities == null) {
eventPerformer.reload();
}
if (entities == null) {
throw new IllegalStateException("Cannot load entities for grid component");
}
JSONObject json = new JSONObject();
json.put(JSON_SELECTED_ENTITY_ID, selectedEntityId);
json.put(JSON_BELONGS_TO_ENTITY_ID, belongsToEntityId);
json.put(JSON_FIRST_ENTITY, firstResult);
json.put(JSON_MAX_ENTITIES, maxResults);
json.put(JSON_FILTERS_ENABLED, filtersEnabled);
json.put(JSON_MULTI_SEARCH_ENABLED, multiSearchEnabled);
json.put(JSON_TOTAL_ENTITIES, totalEntities);
json.put(JSON_ONLY_ACTIVE, onlyActive);
json.put(JSON_ONLY_INACTIVE, onlyInactive);
json.put(JSON_MULTISELECT_MODE, multiselectMode);
JSONObject selectedEntitiesJson = new JSONObject();
for (Long entityId : selectedEntities) {
selectedEntitiesJson.put(entityId.toString(), true);
}
json.put(JSON_SELECTED_ENTITIES, selectedEntitiesJson);
if (isEditable != null) {
json.put(JSON_EDITABLE, isEditable);
}
if (!entitiesToMarkAsNew.isEmpty()) {
JSONObject entitiesToMarkAsNewJson = new JSONObject();
for (Long entityId : entitiesToMarkAsNew) {
entitiesToMarkAsNewJson.put(entityId.toString(), true);
}
json.put(JSON_ENTITIES_TO_MARK_AS_NEW, entitiesToMarkAsNewJson);
}
if (rowStyleResolver != null) {
json.put(JSON_ENTITIES_TO_MARK_WITH_CSS_CLASS, getRowStyles());
}
JSONArray jsonOrderList = new JSONArray();
for (GridComponentOrderColumn orderColumn : orderColumns) {
JSONObject jsonOrder = new JSONObject();
jsonOrder.put(JSON_ORDER_COLUMN, orderColumn.getName());
jsonOrder.put(JSON_ORDER_DIRECTION, orderColumn.getDirection());
jsonOrderList.put(jsonOrder);
}
if (!orderColumns.isEmpty()) {
json.put(JSON_ORDER, jsonOrderList);
}
json.put(JSON_FILTERS, new JSONObject(filters));
json.put(JSON_MULTI_SEARCH_FILTER, multiSearchFilter.toJson());
JSONArray jsonEntities = new JSONArray();
for (Entity entity : entities) {
jsonEntities.put(convertEntityToJson(entity));
}
json.put(JSON_ENTITIES, jsonEntities);
if (criteriaModifierParameter != null) {
json.put(JSON_CRITERIA_MODIFIER_PARAMETER, criteriaModifierParameter);
if (criteriaModifierParameter.has(JSON_HEADER_VALUE)) {
json.put(JSON_HEADER_VALUE, criteriaModifierParameter.getString(JSON_HEADER_VALUE));
}
}
json.put(JSON_DELETE_ENABLED, this.deleteEnabled);
json.put(JSON_AUTOMATIC_REFRESH, this.autoRefresh);
return json;
}
private JSONObject getRowStyles() throws JSONException {
final JSONObject stylesForEntities = new JSONObject();
for (Map.Entry<Long, Set<String>> entityToStyles : rowStyleResolver.resolve(entities).entrySet()) {
stylesForEntities.put(entityToStyles.getKey().toString(), new JSONArray(entityToStyles.getValue()));
}
return stylesForEntities;
}
private JSONObject convertEntityToJson(final Entity entity) throws JSONException {
JSONObject json = new JSONObject();
json.put("id", entity.getId());
if (activable) {
json.put("active", entity.isActive());
} else {
json.put("active", true);
}
JSONObject fields = new JSONObject();
for (GridComponentColumn column : pattern.filterColumnsWithAccess(columns.values())){
fields.put(column.getName(), column.getValue(entity, getLocale()));
}
json.put("fields", fields);
return json;
}
@Override
public Set<Long> getSelectedEntitiesIds() {
return selectedEntities;
}
@Override
public List<Entity> getSelectedEntities() {
if (selectedEntities == null || selectedEntities.isEmpty()) {
return Lists.newArrayList();
}
final SearchCriteriaBuilder searchCriteria = getDataDefinition().find();
searchCriteria.add(SearchRestrictions.in("id", selectedEntities));
return searchCriteria.list().getEntities();
}
@Override
public void setEditable(final boolean isEditable) {
this.isEditable = isEditable;
}
@Override
public void setSelectedEntitiesIds(final Set<Long> selectedEntities) {
this.selectedEntities = selectedEntities;
if (selectedEntities == null || selectedEntities.size() < 2) {
multiselectMode = false;
} else {
multiselectMode = true;
}
}
@Override
public void setEntities(final List<Entity> entities) {
this.entities = entities;
totalEntities = entities.size();
}
@Override
public List<Entity> getEntities() {
if (entities == null) {
eventPerformer.reload();
}
return entities;
}
@Override
public void reloadEntities() {
eventPerformer.reload();
}
private void setSelectedEntityId(final Long selectedEntityId) {
this.selectedEntityId = selectedEntityId;
notifyEntityIdChangeListeners(selectedEntityId);
}
private Long getSelectedEntityId() {
return selectedEntityId;
}
@Override
public Object getFieldValue() {
return getSelectedEntityId();
}
@Override
public void setFieldValue(final Object value) {
setSelectedEntityId((Long) value);
}
@Override
public void setCustomRestriction(final CustomRestriction customRestriction) {
this.customRestriction = customRestriction;
}
protected class GridEventPerformer {
public void refresh(final String[] args) {
// nothing interesting here
}
public void selectEntity(final String[] args) {
notifyEntityIdChangeListeners(getSelectedEntityId());
}
public void addExistingEntity(final String[] selectedEntities) throws JSONException {
if (!weakRelation || selectedEntities.length == 0) {
return;
}
JSONArray selectedEntitiesArray = null;
if (selectedEntities[0].contains("[")) {
selectedEntitiesArray = new JSONArray(selectedEntities[0]);
} else {
selectedEntitiesArray = new JSONArray(selectedEntities);
}
List<Long> selectedEntitiesId = Lists.newArrayList();
for (int i = 0; i < selectedEntitiesArray.length(); i++) {
selectedEntitiesId.add(Long.parseLong(selectedEntitiesArray.getString(i)));
}
List<Entity> existingEntities = getEntities();
List<Entity> newlyAddedEntities = getDataDefinition().find().add(SearchRestrictions.in("id", selectedEntitiesId))
.list().getEntities();
entitiesToMarkAsNew = Sets.newHashSet(selectedEntitiesId);
for (Entity existingEntity : existingEntities) {
entitiesToMarkAsNew.remove(existingEntity.getId());
}
existingEntities.addAll(newlyAddedEntities);
FieldType belongsToFieldType = belongsToFieldDefinition.getType();
if (belongsToFieldType instanceof JoinFieldHolder) {
Entity gridOwnerEntity = scopeFieldDataDefinition.get(belongsToEntityId);
List<Entity> entities = gridOwnerEntity.getManyToManyField(((JoinFieldHolder) belongsToFieldType)
.getJoinFieldName());
entities.addAll(newlyAddedEntities);
gridOwnerEntity.setField(((JoinFieldHolder) belongsToFieldType).getJoinFieldName(), entities);
gridOwnerEntity.getDataDefinition().save(gridOwnerEntity);
copyFieldValidationMessages(gridOwnerEntity);
} else if (belongsToFieldType instanceof BelongsToType) {
for (Entity entity : newlyAddedEntities) {
entity.setField(belongsToFieldDefinition.getName(), belongsToEntityId);
entity.getDataDefinition().save(entity);
copyFieldValidationMessages(entity);
}
} else {
throw new IllegalArgumentException("Unsupported relation type - " + belongsToFieldDefinition.getType().toString());
}
reload();
}
public void removeSelectedEntity(final String[] args) {
EntityOpResult result = EntityOpResult.successfull();
if (weakRelation) {
Entity entity = null;
boolean isManyToManyRelationType = belongsToFieldDefinition.getType() instanceof JoinFieldHolder;
Long[] selectedEntitiesIds = selectedEntities.toArray(new Long[selectedEntities.size()]);
if (isManyToManyRelationType) {
String gridFieldName = ((JoinFieldHolder) belongsToFieldDefinition.getType()).getJoinFieldName();
Entity gridOwnerEntity = scopeFieldDataDefinition.get(belongsToEntityId);
List<Entity> relatedEntities = gridOwnerEntity.getManyToManyField(gridFieldName);
for (Long selectedId : selectedEntitiesIds) {
relatedEntities.remove(new ProxyEntity(getDataDefinition(), selectedId));
}
gridOwnerEntity.setField(gridFieldName, relatedEntities);
scopeFieldDataDefinition.save(gridOwnerEntity);
copyFieldValidationMessages(gridOwnerEntity);
} else {
for (Long selectedId : selectedEntitiesIds) {
entity = getDataDefinition().get(selectedId);
entity.setField(belongsToFieldDefinition.getName(), null);
getDataDefinition().save(entity);
copyFieldValidationMessages(entity);
}
}
} else {
result = getDataDefinition().delete(selectedEntities.toArray(new Long[selectedEntities.size()]));
}
if (result.isSuccessfull()) {
if (selectedEntities.size() == 1) {
addTranslatedMessage(translateMessage("deleteMessage"), MessageType.SUCCESS);
} else {
addTranslatedMessage(translateMessage("deleteMessages", String.valueOf(selectedEntities.size())),
MessageType.SUCCESS);
}
setSelectedEntityId(null);
multiselectMode = false;
selectedEntities = new HashSet<Long>();
} else {
copyMessages(result.getMessagesHolder().getGlobalErrors());
}
copyGlobalMessages(result.getMessagesHolder().getGlobalMessages());
}
public void moveUpSelectedEntity(final String[] args) {
getDataDefinition().move(selectedEntityId, -1);
addTranslatedMessage(translateMessage("moveMessage"), MessageType.SUCCESS);
}
public void deactivateSelectedEntity(final String[] args) {
List<Entity> deactivatedEntities = getDataDefinition().deactivate(
selectedEntities.toArray(new Long[selectedEntities.size()]));
entitiesToMarkAsNew = new HashSet<Long>();
for (Entity entity : deactivatedEntities) {
entitiesToMarkAsNew.add(entity.getId());
}
if (selectedEntities.size() == 1) {
addTranslatedMessage(translateMessage("deactivateMessage"), MessageType.SUCCESS);
} else {
addTranslatedMessage(translateMessage("deactivateMessages", String.valueOf(selectedEntities.size())),
MessageType.SUCCESS);
}
}
public void activateSelectedEntity(final String[] args) {
List<Entity> activatedEntities = getDataDefinition().activate(
selectedEntities.toArray(new Long[selectedEntities.size()]));
entitiesToMarkAsNew = new HashSet<Long>();
for (Entity entity : activatedEntities) {
entitiesToMarkAsNew.add(entity.getId());
}
if (selectedEntities.size() == 1) {
addTranslatedMessage(translateMessage("activateMessage"), MessageType.SUCCESS);
} else {
addTranslatedMessage(translateMessage("activateMessages", String.valueOf(selectedEntities.size())),
MessageType.SUCCESS);
}
}
public void copySelectedEntity(final String[] args) {
List<Entity> copiedEntities = getDataDefinition().copy(selectedEntities.toArray(new Long[selectedEntities.size()]));
entitiesToMarkAsNew = new HashSet<Long>();
for (Entity copiedEntity : copiedEntities) {
entitiesToMarkAsNew.add(copiedEntity.getId());
}
if (selectedEntities.size() == 1) {
addTranslatedMessage(translateMessage("copyMessage"), MessageType.SUCCESS);
} else {
addTranslatedMessage(translateMessage("copyMessages", String.valueOf(selectedEntities.size())),
MessageType.SUCCESS);
}
}
public void moveDownSelectedEntity(final String[] args) {
getDataDefinition().move(selectedEntityId, 1);
addTranslatedMessage(translateMessage("moveMessage"), MessageType.SUCCESS);
}
private void reload() {
if (belongsToFieldDefinition == null || belongsToEntityId != null) {
SearchCriteriaBuilder criteria = getDataDefinition().find();
if (belongsToFieldDefinition != null && !useDto) {
if (belongsToFieldDefinition.getType() instanceof ManyToManyType) {
String belongsToFieldName = belongsToFieldDefinition.getName();
criteria.createAlias(belongsToFieldName, belongsToFieldName).add(
SearchRestrictions.eq(belongsToFieldName + ".id", belongsToEntityId));
} else {
// criteria.add(SearchRestrictions.belongsTo(belongsToFieldDefinition.getName(), ((DataDefinitionHolder)
// belongsToFieldDefinition.getType()).getDataDefinition(), belongsToEntityId));
criteria.add(SearchRestrictions.eq(belongsToFieldDefinition.getName() + ".id", belongsToEntityId));
}
}
if (useDto) {
criteria.add(SearchRestrictions.eq(buildDtoIdFieldName(belongsToFieldDefinition.getName()),
belongsToEntityId.intValue()));
}
try {
if (filtersEnabled) {
GridComponentFilterUtils.addFilters(filters, columns, getDataDefinition(), criteria);
}
if (multiSearchEnabled) {
GridComponentFilterUtils.addMultiSearchFilter(multiSearchFilter, columns, getDataDefinition(), criteria);
}
if (customRestriction != null) {
customRestriction.addRestriction(criteria);
}
if (activable && onlyActive) {
criteria.add(SearchRestrictions.eq("active", true));
}
if (activable && onlyInactive) {
criteria.add(SearchRestrictions.eq("active", false));
}
addOrder(criteria);
addPaging(criteria);
if (criteriaModifier != null) {
criteriaModifier.modifyCriteria(criteria, criteriaModifierParameter);
}
SearchResult result = criteria.list();
if (repeatWithFixedFirstResult(result)) {
addPaging(criteria);
result = criteria.list();
}
entities = result.getEntities();
totalEntities = result.getTotalNumberOfEntities();
} catch (GridComponentFilterException gcfe) {
addMessage("qcadooView.grid.filter.incorrectValue", MessageType.FAILURE, gcfe.getFilterValue());
clear();
}
} else {
clear();
}
}
private void clear() {
entities = Collections.emptyList();
totalEntities = 0;
}
private void addPaging(final SearchCriteriaBuilder criteria) {
criteria.setFirstResult(firstResult);
criteria.setMaxResults(maxResults);
}
private void addOrder(final SearchCriteriaBuilder criteria) {
for (GridComponentOrderColumn orderColumn : orderColumns) {
String field = GridComponentFilterUtils.getFieldNameByColumnName(columns, orderColumn.getName());
field = GridComponentFilterUtils.addAliases(criteria, field, JoinType.LEFT);
if (field != null) {
if ("asc".equals(orderColumn.getDirection())) {
criteria.addOrder(SearchOrders.asc(field));
} else {
criteria.addOrder(SearchOrders.desc(field));
}
}
}
}
private boolean repeatWithFixedFirstResult(final SearchResult result) {
if (result.getEntities().isEmpty() && result.getTotalNumberOfEntities() > 0) {
while (firstResult >= result.getTotalNumberOfEntities()) {
firstResult -= maxResults;
}
return true;
} else {
return false;
}
}
}
private String buildDtoIdFieldName(final String name) {
StringBuffer dtoKey = new StringBuffer();
dtoKey.append(name);
dtoKey.append("Id");
return dtoKey.toString();
}
@Override
public Map<String, String> getColumnNames() {
Map<String, String> names = new LinkedHashMap<String, String>();
for (GridComponentColumn column : pattern.filterColumnsWithAccess(columns.values())){
if (column.isHidden()) {
continue;
}
if (column.getFields().size() == 1) {
String fieldCode = getDataDefinition().getPluginIdentifier() + "." + getDataDefinition().getName() + "."
+ column.getFields().get(0).getName();
names.put(
column.getName(),
getTranslationService().translate(getTranslationPath() + ".column." + column.getName(),
fieldCode + ".label", getLocale()));
} else {
names.put(column.getName(),
getTranslationService().translate(getTranslationPath() + ".column." + column.getName(), getLocale()));
}
}
return names;
}
@Override
public List<Map<String, String>> getColumnValuesOfAllRecords() {
return getColumnValues(ExportMode.ALL);
}
@Override
public List<Map<String, String>> getColumnValuesOfSelectedRecords() {
return getColumnValues(ExportMode.SELECTED);
}
private List<Map<String, String>> getColumnValues(final ExportMode mode) {
if (entities == null) {
eventPerformer.reload();
}
if (entities == null) {
throw new IllegalStateException("Cannot load entities for grid component");
}
List<Map<String, String>> values = new ArrayList<Map<String, String>>();
for (Entity entity : entities) {
if (mode == ExportMode.ALL || (mode == ExportMode.SELECTED && getSelectedEntitiesIds().contains(entity.getId()))) {
values.add(convertEntityToMap(entity));
}
}
return values;
}
private Map<String, String> convertEntityToMap(final Entity entity) {
Map<String, String> values = new LinkedHashMap<String, String>();
for (GridComponentColumn column : pattern.filterColumnsWithAccess(columns.values())){
if (column.isHidden()) {
continue;
}
if (column.getFields().get(0).getType() instanceof EnumType) {
String fieldValue = column.getValue(entity, getLocale());
StringBuffer localeString = new StringBuffer();
localeString.append(getDataDefinition().getPluginIdentifier());
localeString.append('.');
localeString.append(getDataDefinition().getName());
localeString.append('.');
localeString.append(column.getName());
localeString.append(".value.");
localeString.append(fieldValue);
values.put(column.getName(), getTranslationService().translate(localeString.toString(), getLocale()));
} else if (column.getFields().get(0).getType().getType().equals(Boolean.class)) {
String fieldValue = column.getValue(entity, getLocale());
if (fieldValue != null) {
if (fieldValue.equals("1")) {
values.put(column.getName(), getTranslationService().translate("qcadooView.true", getLocale()));
} else {
values.put(column.getName(), getTranslationService().translate("qcadooView.false", getLocale()));
}
} else {
values.put(column.getName(), "");
}
} else {
values.put(column.getName(), column.getValue(entity, getLocale()));
}
}
return values;
}
private void copyFieldValidationMessages(final Entity messagesSource) {
for (ErrorMessage message : messagesSource.getErrors().values()) {
addMessage(message);
}
}
@Override
public FilterValueHolder getFilterValue() {
if (criteriaModifier == null) {
throw new IllegalStateException("There is no critieria modifier. Filter value is not present.");
}
FilterValueHolder holder = new FilterValueHolderImpl(criteriaModifierParameter);
return holder;
}
@Override
public void setFilterValue(final FilterValueHolder value) {
if (criteriaModifier == null) {
throw new IllegalStateException("There is no critieria modifier, can't set filter value.");
}
criteriaModifierParameter.initialize(value.toJSON());
requestRender();
}
@Override
public Map<String, String> getFilters() {
return filters;
}
@Override
public void setFilters(Map<String, String> newFilters) {
filters.putAll(newFilters);
}
@Override
public Map<String, GridComponentColumn> getColumns() {
return columns;
}
@Override
public GridComponentMultiSearchFilter getMultiSearchFilter() {
return multiSearchFilter;
}
}