diff --git a/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewFactory.java b/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewFactory.java index 2d0b31051..8921c1eb8 100644 --- a/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewFactory.java +++ b/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewFactory.java @@ -60,7 +60,7 @@ public ViewLayout getViewLayout(final WindowId windowId, final JSONViewDataType } @Override - public Collection getViewFilters(final WindowId windowId, final JSONViewDataType viewType) + public Collection getViewFilterDescriptors(final WindowId windowId, final JSONViewDataType viewType) { return null; // not supported } diff --git a/src/main/java/de/metas/ui/web/pporder/PPOrderLinesViewFactory.java b/src/main/java/de/metas/ui/web/pporder/PPOrderLinesViewFactory.java index 48cda6e66..f95a5c6fc 100644 --- a/src/main/java/de/metas/ui/web/pporder/PPOrderLinesViewFactory.java +++ b/src/main/java/de/metas/ui/web/pporder/PPOrderLinesViewFactory.java @@ -70,7 +70,7 @@ public ViewLayout getViewLayout(final WindowId windowId, final JSONViewDataType } @Override - public Collection getViewFilters(final WindowId windowId, final JSONViewDataType viewType) + public Collection getViewFilterDescriptors(final WindowId windowId, final JSONViewDataType viewType) { return null; // not supported } diff --git a/src/main/java/de/metas/ui/web/view/SqlView.java b/src/main/java/de/metas/ui/web/view/DefaultView.java similarity index 73% rename from src/main/java/de/metas/ui/web/view/SqlView.java rename to src/main/java/de/metas/ui/web/view/DefaultView.java index 34aff2d47..70a41b692 100644 --- a/src/main/java/de/metas/ui/web/view/SqlView.java +++ b/src/main/java/de/metas/ui/web/view/DefaultView.java @@ -10,12 +10,7 @@ import javax.annotation.Nullable; -import org.adempiere.ad.dao.IQueryBL; -import org.adempiere.ad.dao.impl.TypedSqlQueryFilter; -import org.adempiere.exceptions.DBException; -import org.adempiere.model.PlainContextAware; import org.adempiere.util.GuavaCollectors; -import org.adempiere.util.Services; import org.adempiere.util.lang.impl.TableRecordReference; import org.compiere.util.CCache; import org.compiere.util.Env; @@ -27,7 +22,6 @@ import de.metas.logging.LogManager; import de.metas.ui.web.exceptions.EntityNotFoundException; -import de.metas.ui.web.view.descriptor.SqlViewBinding; import de.metas.ui.web.view.event.ViewChangesCollector; import de.metas.ui.web.window.datatypes.DocumentId; import de.metas.ui.web.window.datatypes.LookupValuesList; @@ -60,18 +54,25 @@ * #L% */ -class SqlView implements IView +/** + * Default {@link IView} implementation. + * + * @author metas-dev + * + */ +class DefaultView implements IView { - public static final Builder builder(final SqlViewBinding sqlViewBinding) + public static final Builder builder(final IViewDataRepository viewDataRepository) { - return new Builder(sqlViewBinding); + return new Builder(viewDataRepository); } - private static final Logger logger = LogManager.getLogger(SqlView.class); + private static final Logger logger = LogManager.getLogger(DefaultView.class); + + private final IViewDataRepository viewDataRepository; private final AtomicBoolean closed = new AtomicBoolean(false); private final ViewId parentViewId; - private final SqlViewRepository viewRowsRepo; private final transient IViewRowIdsOrderedSelectionFactory orderedSelectionFactory; private final transient ViewRowIdsOrderedSelection defaultSelection; @@ -79,16 +80,12 @@ public static final Builder builder(final SqlViewBinding sqlViewBinding) // // Filters - private final transient DocumentFilterDescriptorsProvider filterDescriptors; + private final transient DocumentFilterDescriptorsProvider viewFilterDescriptors; /** Sticky filters (i.e. active filters which cannot be changed) */ private final List stickyFilters; /** Active filters */ private final List filters; - // - // Attributes - private final transient IViewRowAttributesProvider attributesProvider; - // // Misc private transient String _toString; @@ -97,24 +94,24 @@ public static final Builder builder(final SqlViewBinding sqlViewBinding) // Caching private final transient CCache cache_rowsById; - private SqlView(final Builder builder) + private DefaultView(final Builder builder) { - viewRowsRepo = new SqlViewRepository(builder.getSqlViewBinding()); + viewDataRepository = builder.getViewDataRepository(); parentViewId = builder.getParentViewId(); // // Filters - filterDescriptors = builder.getFilterDescriptors(); + viewFilterDescriptors = builder.getViewFilterDescriptors(); stickyFilters = ImmutableList.copyOf(builder.getStickyFilters()); filters = ImmutableList.copyOf(builder.getFilters()); // // Selection { - final SqlViewEvaluationCtx evalCtx = SqlViewEvaluationCtx.of(Env.getCtx()); - orderedSelectionFactory = viewRowsRepo.createOrderedSelectionFactory(evalCtx); + final ViewEvaluationCtx evalCtx = ViewEvaluationCtx.of(Env.getCtx()); + orderedSelectionFactory = viewDataRepository.createOrderedSelectionFactory(evalCtx); - defaultSelection = viewRowsRepo.createOrderedSelection( + defaultSelection = viewDataRepository.createOrderedSelection( evalCtx // , builder.getWindowId() // , ImmutableList. builder().addAll(stickyFilters).addAll(filters).build() // @@ -122,14 +119,10 @@ private SqlView(final Builder builder) selectionsByOrderBys.put(defaultSelection.getOrderBys(), defaultSelection); } - // - // Attributes - attributesProvider = ViewRowAttributesProviderFactory.instance.createProviderOrNull(defaultSelection.getWindowId()); - // // Cache cache_rowsById = CCache.newLRUCache( // - viewRowsRepo.getTableName() + "#rowById#viewId=" + defaultSelection.getSelectionId() // cache name + viewDataRepository.getTableName() + "#rowById#viewId=" + defaultSelection.getSelectionId() // cache name , 100 // maxSize , 2 // expireAfterMinutes ); @@ -142,14 +135,13 @@ public String toString() { if (_toString == null) { + // NOTE: keep it short _toString = MoreObjects.toStringHelper(this) .omitNullValues() .add("viewId", defaultSelection.getViewId()) - .add("tableName", viewRowsRepo.getTableName()) + .add("tableName", viewDataRepository.getTableName()) .add("parentViewId", parentViewId) .add("defaultSelection", defaultSelection) - // .add("sql", sqlSelectPage) // too long.. - // .add("fieldLoaders", fieldLoaders) // no point to show them because all are lambdas .toString(); } return _toString; @@ -170,7 +162,7 @@ public ViewId getViewId() @Override public String getTableName() { - return viewRowsRepo.getTableName(); + return viewDataRepository.getTableName(); } @Override @@ -232,14 +224,14 @@ private final void assertNotClosed() } @Override - public ViewResult getPage(final int firstRow, final int pageLength, final List orderBys) throws DBException + public ViewResult getPage(final int firstRow, final int pageLength, final List orderBys) { assertNotClosed(); - final SqlViewEvaluationCtx evalCtx = SqlViewEvaluationCtx.of(Env.getCtx()); + final ViewEvaluationCtx evalCtx = ViewEvaluationCtx.of(Env.getCtx()); final ViewRowIdsOrderedSelection orderedSelection = getOrderedSelection(orderBys); - final List page = viewRowsRepo.retrievePage(evalCtx, orderedSelection, firstRow, pageLength); + final List page = viewDataRepository.retrievePage(evalCtx, orderedSelection, firstRow, pageLength); // Add to cache page.forEach(row -> cache_rowsById.put(row.getId(), row)); @@ -257,12 +249,12 @@ public IViewRow getById(final DocumentId rowId) private final IViewRow getOrRetrieveById(final DocumentId rowId) { return cache_rowsById.getOrLoad(rowId, () -> { - final SqlViewEvaluationCtx evalCtx = SqlViewEvaluationCtx.of(Env.getCtx()); - return viewRowsRepo.retrieveById(evalCtx, getViewId(), rowId); + final ViewEvaluationCtx evalCtx = ViewEvaluationCtx.of(Env.getCtx()); + return viewDataRepository.retrieveById(evalCtx, getViewId(), rowId); }); } - private ViewRowIdsOrderedSelection getOrderedSelection(final List orderBys) throws DBException + private ViewRowIdsOrderedSelection getOrderedSelection(final List orderBys) { if (orderBys == null || orderBys.isEmpty()) { @@ -274,14 +266,13 @@ private ViewRowIdsOrderedSelection getOrderedSelection(final List orderBysImmutable = ImmutableList.copyOf(orderBys); - return selectionsByOrderBys.computeIfAbsent(orderBysImmutable, (newOrderBys) -> orderedSelectionFactory.createFromView(defaultSelection, orderBysImmutable)); + return selectionsByOrderBys.computeIfAbsent(ImmutableList.copyOf(orderBys), orderBysImmutable -> orderedSelectionFactory.createFromView(defaultSelection, orderBysImmutable)); } @Override public String getSqlWhereClause(final Collection rowIds) { - return viewRowsRepo.getSqlWhereClause(getViewId(), rowIds); + return viewDataRepository.getSqlWhereClause(getViewId(), rowIds); } @Override @@ -289,7 +280,7 @@ public LookupValuesList getFilterParameterDropdown(final String filterId, final { assertNotClosed(); - return filterDescriptors.getByFilterId(filterId) + return viewFilterDescriptors.getByFilterId(filterId) .getParameterByName(filterParameterName) .getLookupDataSource() .findEntities(ctx); @@ -300,7 +291,7 @@ public LookupValuesList getFilterParameterTypeahead(final String filterId, final { assertNotClosed(); - return filterDescriptors.getByFilterId(filterId) + return viewFilterDescriptors.getByFilterId(filterId) .getParameterByName(filterParameterName) .getLookupDataSource() .findEntities(ctx, query); @@ -309,7 +300,7 @@ public LookupValuesList getFilterParameterTypeahead(final String filterId, final @Override public boolean hasAttributesSupport() { - return attributesProvider != null; + return false; } @Override @@ -340,17 +331,7 @@ public Stream streamByIds(final Collection rowId @Override public List retrieveModelsByIds(final Collection rowIds, final Class modelClass) { - if (rowIds.isEmpty()) - { - return ImmutableList.of(); - } - - final String sqlWhereClause = getSqlWhereClause(rowIds); - - return Services.get(IQueryBL.class).createQueryBuilder(modelClass, getTableName(), PlainContextAware.createUsingOutOfTransaction()) - .filter(new TypedSqlQueryFilter<>(sqlWhereClause)) - .create() - .list(modelClass); + return viewDataRepository.retrieveModelsByIds(getViewId(), rowIds, modelClass); } @Override @@ -385,19 +366,19 @@ public static final class Builder { private WindowId windowId; private ViewId parentViewId; - private final SqlViewBinding sqlViewBinding; + private final IViewDataRepository viewDataRepository; private List _stickyFilters; private List _filters; - private Builder(@NonNull final SqlViewBinding sqlViewBinding) + private Builder(@NonNull final IViewDataRepository viewDataRepository) { - this.sqlViewBinding = sqlViewBinding; + this.viewDataRepository = viewDataRepository; } - public SqlView build() + public DefaultView build() { - return new SqlView(this); + return new DefaultView(this); } public Builder setParentViewId(final ViewId parentViewId) @@ -422,14 +403,14 @@ private ViewId getParentViewId() return parentViewId; } - private SqlViewBinding getSqlViewBinding() + private IViewDataRepository getViewDataRepository() { - return sqlViewBinding; + return viewDataRepository; } - private DocumentFilterDescriptorsProvider getFilterDescriptors() + private DocumentFilterDescriptorsProvider getViewFilterDescriptors() { - return sqlViewBinding.getFilterDescriptors(); + return viewDataRepository.getViewFilterDescriptors(); } public Builder setStickyFilter(@Nullable final DocumentFilter stickyFilter) @@ -451,7 +432,7 @@ public Builder setFilters(final List filters) public Builder setFiltersFromJSON(final List jsonFilters) { - setFilters(JSONDocumentFilter.unwrapList(jsonFilters, getFilterDescriptors())); + setFilters(JSONDocumentFilter.unwrapList(jsonFilters, getViewFilterDescriptors())); return this; } diff --git a/src/main/java/de/metas/ui/web/view/IViewDataRepository.java b/src/main/java/de/metas/ui/web/view/IViewDataRepository.java new file mode 100644 index 000000000..7a8293832 --- /dev/null +++ b/src/main/java/de/metas/ui/web/view/IViewDataRepository.java @@ -0,0 +1,59 @@ +package de.metas.ui.web.view; + +import java.util.Collection; +import java.util.List; + +import org.adempiere.exceptions.DBException; + +import de.metas.ui.web.window.datatypes.DocumentId; +import de.metas.ui.web.window.datatypes.WindowId; +import de.metas.ui.web.window.descriptor.filters.DocumentFilterDescriptorsProvider; +import de.metas.ui.web.window.model.filters.DocumentFilter; + +/* + * #%L + * metasfresh-webui-api + * %% + * Copyright (C) 2017 metas GmbH + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +/** + * View data repository. + * This repository is responsible for fetching {@link IViewRow} or even their models. + * + * @author metas-dev + * + */ +interface IViewDataRepository +{ + String getTableName(); + + String getSqlWhereClause(ViewId viewId, Collection rowIds); + + DocumentFilterDescriptorsProvider getViewFilterDescriptors(); + + IViewRow retrieveById(ViewEvaluationCtx viewEvalCtx, ViewId viewId, DocumentId rowId); + + List retrievePage(ViewEvaluationCtx viewEvalCtx, ViewRowIdsOrderedSelection orderedSelection, int firstRow, int pageLength) throws DBException; + + List retrieveModelsByIds(ViewId viewId, Collection rowIds, Class modelClass); + + IViewRowIdsOrderedSelectionFactory createOrderedSelectionFactory(ViewEvaluationCtx viewEvalCtx); + + ViewRowIdsOrderedSelection createOrderedSelection(ViewEvaluationCtx viewEvalCtx, WindowId windowId, List filters); +} diff --git a/src/main/java/de/metas/ui/web/view/IViewFactory.java b/src/main/java/de/metas/ui/web/view/IViewFactory.java index 4c843a3a9..000790253 100644 --- a/src/main/java/de/metas/ui/web/view/IViewFactory.java +++ b/src/main/java/de/metas/ui/web/view/IViewFactory.java @@ -33,7 +33,7 @@ public interface IViewFactory { ViewLayout getViewLayout(WindowId windowId, JSONViewDataType viewDataType); - Collection getViewFilters(WindowId windowId, JSONViewDataType viewDataType); + Collection getViewFilterDescriptors(WindowId windowId, JSONViewDataType viewDataType); IView createView(ViewCreateRequest request); diff --git a/src/main/java/de/metas/ui/web/view/IViewsRepository.java b/src/main/java/de/metas/ui/web/view/IViewsRepository.java index c4205964b..44d39bc1c 100644 --- a/src/main/java/de/metas/ui/web/view/IViewsRepository.java +++ b/src/main/java/de/metas/ui/web/view/IViewsRepository.java @@ -8,8 +8,8 @@ import com.google.common.collect.ImmutableSet; -import de.metas.ui.web.view.json.JSONViewLayout; import de.metas.ui.web.view.json.JSONViewDataType; +import de.metas.ui.web.view.json.JSONViewLayout; import de.metas.ui.web.window.datatypes.WindowId; import de.metas.ui.web.window.datatypes.json.JSONOptions; import lombok.NonNull; @@ -36,6 +36,12 @@ * #L% */ +/** + * {@link IView}s repository. + * + * @author metas-dev + * + */ public interface IViewsRepository { JSONViewLayout getViewLayout(WindowId windowId, JSONViewDataType viewDataType, JSONOptions jsonOpts); diff --git a/src/main/java/de/metas/ui/web/view/SqlViewRepository.java b/src/main/java/de/metas/ui/web/view/SqlViewDataRepository.java similarity index 79% rename from src/main/java/de/metas/ui/web/view/SqlViewRepository.java rename to src/main/java/de/metas/ui/web/view/SqlViewDataRepository.java index cbb6fe67f..d8d4fad79 100644 --- a/src/main/java/de/metas/ui/web/view/SqlViewRepository.java +++ b/src/main/java/de/metas/ui/web/view/SqlViewDataRepository.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.Map; +import org.adempiere.ad.dao.IQueryBL; +import org.adempiere.ad.dao.impl.TypedSqlQueryFilter; import org.adempiere.ad.expression.api.IExpressionEvaluator.OnVariableNotFound; import org.adempiere.ad.security.IUserRolePermissions; import org.adempiere.ad.security.IUserRolePermissionsDAO; @@ -15,10 +17,10 @@ import org.adempiere.ad.security.permissions.WindowMaxQueryRecordsConstraint; import org.adempiere.ad.trx.api.ITrx; import org.adempiere.exceptions.DBException; +import org.adempiere.model.PlainContextAware; import org.adempiere.util.Check; import org.adempiere.util.Services; import org.compiere.util.DB; -import org.compiere.util.Evaluatee; import org.slf4j.Logger; import com.google.common.base.MoreObjects; @@ -33,6 +35,7 @@ import de.metas.ui.web.view.descriptor.SqlViewRowIdsOrderedSelectionFactory; import de.metas.ui.web.window.datatypes.DocumentId; import de.metas.ui.web.window.datatypes.WindowId; +import de.metas.ui.web.window.descriptor.filters.DocumentFilterDescriptorsProvider; import de.metas.ui.web.window.model.filters.DocumentFilter; import lombok.NonNull; @@ -58,13 +61,13 @@ * #L% */ -class SqlViewRepository +class SqlViewDataRepository implements IViewDataRepository { - private static final Logger logger = LogManager.getLogger(SqlViewRepository.class); + private static final Logger logger = LogManager.getLogger(SqlViewDataRepository.class); private final SqlViewBinding sqlBindings; - SqlViewRepository(@NonNull final SqlViewBinding sqlBindings) + SqlViewDataRepository(@NonNull final SqlViewBinding sqlBindings) { this.sqlBindings = sqlBindings; } @@ -75,27 +78,31 @@ public String toString() return MoreObjects.toStringHelper(this).addValue(sqlBindings).toString(); } + @Override public String getTableName() { return sqlBindings.getTableName(); } + @Override public String getSqlWhereClause(final ViewId viewId, final Collection rowIds) { return sqlBindings.getSqlWhereClause(viewId.getViewId(), rowIds); } - public IViewRowIdsOrderedSelectionFactory createOrderedSelectionFactory(final SqlViewEvaluationCtx viewEvalCtx) + @Override + public IViewRowIdsOrderedSelectionFactory createOrderedSelectionFactory(final ViewEvaluationCtx viewEvalCtx) { final String sqlCreateFromViewId = sqlBindings.getSqlCreateSelectionFromSelection(); final Map sqlOrderBysByFieldName = sqlBindings.getSqlOrderBysIndexedByFieldName(viewEvalCtx); return new SqlViewRowIdsOrderedSelectionFactory(sqlCreateFromViewId, sqlOrderBysByFieldName); } - public ViewRowIdsOrderedSelection createOrderedSelection(final SqlViewEvaluationCtx viewEvalCtx, final WindowId windowId, final List filters) + @Override + public ViewRowIdsOrderedSelection createOrderedSelection(final ViewEvaluationCtx viewEvalCtx, final WindowId windowId, final List filters) { final ViewId viewId = ViewId.random(windowId); - + final UserRolePermissionsKey permissionsKey = viewEvalCtx.getPermissionsKey(); final IUserRolePermissions permissions = Services.get(IUserRolePermissionsDAO.class).retrieveUserRolePermissions(permissionsKey); final int queryLimit = permissions.getConstraint(WindowMaxQueryRecordsConstraint.class) @@ -122,13 +129,13 @@ public ViewRowIdsOrderedSelection createOrderedSelection(final SqlViewEvaluation .build(); } - public IViewRow retrieveById(final SqlViewEvaluationCtx viewEvalCtx, final ViewId viewId, final DocumentId rowId) + @Override + public IViewRow retrieveById(final ViewEvaluationCtx viewEvalCtx, final ViewId viewId, final DocumentId rowId) { final WindowId windowId = viewId.getWindowId(); final String viewSelectionId = viewId.getViewId(); - final Evaluatee evalCtx = viewEvalCtx.toEvaluatee(); - final String sql = sqlBindings.getSqlSelectById().evaluate(evalCtx, OnVariableNotFound.Fail); + final String sql = sqlBindings.getSqlSelectById().evaluate(viewEvalCtx.toEvaluatee(), OnVariableNotFound.Fail); final Object[] sqlParams = new Object[] { viewSelectionId, rowId.toInt() }; PreparedStatement pstmt = null; @@ -206,8 +213,15 @@ private IViewRow loadViewRow(final ResultSet rs, final WindowId windowId) throws return viewRowBuilder.build(); } + + @Override + public DocumentFilterDescriptorsProvider getViewFilterDescriptors() + { + return sqlBindings.getViewFilterDescriptors(); + } - public List retrievePage(final SqlViewEvaluationCtx viewEvalCtx, final ViewRowIdsOrderedSelection orderedSelection, final int firstRow, final int pageLength) throws DBException + @Override + public List retrievePage(final ViewEvaluationCtx viewEvalCtx, final ViewRowIdsOrderedSelection orderedSelection, final int firstRow, final int pageLength) throws DBException { logger.debug("Getting page: firstRow={}, pageLength={} - {}", firstRow, pageLength, this); @@ -221,8 +235,7 @@ public List retrievePage(final SqlViewEvaluationCtx viewEvalCtx, final final int firstSeqNo = firstRow + 1; // NOTE: firstRow is 0-based while SeqNo are 1-based final int lastSeqNo = firstRow + pageLength; - final Evaluatee evalCtx = viewEvalCtx.toEvaluatee(); - final String sql = sqlBindings.getSqlSelectByPage().evaluate(evalCtx, OnVariableNotFound.Fail); + final String sql = sqlBindings.getSqlSelectByPage().evaluate(viewEvalCtx.toEvaluatee(), OnVariableNotFound.Fail); final Object[] sqlParams = new Object[] { viewSelectionId, firstSeqNo, lastSeqNo }; PreparedStatement pstmt = null; ResultSet rs = null; @@ -260,4 +273,25 @@ public List retrievePage(final SqlViewEvaluationCtx viewEvalCtx, final } } + @Override + public List retrieveModelsByIds(final ViewId viewId, final Collection rowIds, final Class modelClass) + { + if (rowIds.isEmpty()) + { + return ImmutableList.of(); + } + + final String sqlWhereClause = getSqlWhereClause(viewId, rowIds); + if (Check.isEmpty(sqlWhereClause, true)) + { + logger.warn("Could get the SQL where clause for {}/{}. Returning empty", viewId, rowIds); + return ImmutableList.of(); + } + + return Services.get(IQueryBL.class).createQueryBuilder(modelClass, getTableName(), PlainContextAware.createUsingOutOfTransaction()) + .filter(new TypedSqlQueryFilter<>(sqlWhereClause)) + .create() + .list(modelClass); + } + } diff --git a/src/main/java/de/metas/ui/web/view/SqlViewFactory.java b/src/main/java/de/metas/ui/web/view/SqlViewFactory.java index d0b3dfd6f..5a31fe25f 100644 --- a/src/main/java/de/metas/ui/web/view/SqlViewFactory.java +++ b/src/main/java/de/metas/ui/web/view/SqlViewFactory.java @@ -22,6 +22,7 @@ import de.metas.ui.web.window.descriptor.DocumentLayoutDescriptor; import de.metas.ui.web.window.descriptor.factory.DocumentDescriptorFactory; import de.metas.ui.web.window.descriptor.filters.DocumentFilterDescriptor; +import de.metas.ui.web.window.descriptor.filters.DocumentFilterDescriptorsProvider; import de.metas.ui.web.window.descriptor.sql.SqlDocumentEntityDataBindingDescriptor; import de.metas.ui.web.window.descriptor.sql.SqlDocumentFieldDataBindingDescriptor; import de.metas.ui.web.window.descriptor.sql.SqlDocumentFieldDataBindingDescriptor.DocumentFieldValueLoader; @@ -98,10 +99,10 @@ public ViewLayout getViewLayout(final WindowId windowId, final JSONViewDataType } @Override - public Collection getViewFilters(final WindowId windowId, final JSONViewDataType viewType) + public Collection getViewFilterDescriptors(final WindowId windowId, final JSONViewDataType viewType) { final SqlViewBindingKey sqlViewBindingKey = new SqlViewBindingKey(windowId, viewType.getRequiredFieldCharacteristic()); - return getViewBinding(sqlViewBindingKey).getFilterDescriptors().getAll(); + return getViewBinding(sqlViewBindingKey).getViewFilterDescriptors().getAll(); } @Override @@ -113,7 +114,10 @@ public IView createView(final ViewCreateRequest request) } final SqlViewBindingKey sqlViewBindingKey = new SqlViewBindingKey(request.getWindowId(), request.getViewTypeRequiredFieldCharacteristic()); - return SqlView.builder(getViewBinding(sqlViewBindingKey)) + final SqlViewBinding sqlViewBinding = getViewBinding(sqlViewBindingKey); + final SqlViewDataRepository sqlViewDataRepository = new SqlViewDataRepository(sqlViewBinding); + + return DefaultView.builder(sqlViewDataRepository) .setWindowId(request.getWindowId()) .setParentViewId(request.getParentViewId()) .setStickyFilter(extractReferencedDocumentFilter(request.getWindowId(), request.getSingleReferencingDocumentPathOrNull())) @@ -143,14 +147,14 @@ private SqlViewBinding createViewBinding(final SqlViewBindingKey key) { final DocumentEntityDescriptor entityDescriptor = documentDescriptorFactory.getDocumentEntityDescriptor(key.getWindowId()); final Set displayFieldNames = entityDescriptor.getFieldNamesWithCharacteristic(key.getRequiredFieldCharacteristic()); - final SqlDocumentEntityDataBindingDescriptor entityBinding = SqlDocumentEntityDataBindingDescriptor.cast(entityDescriptor.getDataBinding()); - + final DocumentFilterDescriptorsProvider filterDescriptors = entityDescriptor.getFiltersProvider(); + final SqlViewBinding.Builder builder = SqlViewBinding.builder() .setTableName(entityBinding.getTableName()) .setTableAlias(entityBinding.getTableAlias()) .setDisplayFieldNames(displayFieldNames) - .setFilterDescriptors(entityDescriptor.getFiltersProvider()) + .setViewFilterDescriptors(filterDescriptors) .setOrderBys(entityBinding.getDefaultOrderBys()); entityBinding.getFields() diff --git a/src/main/java/de/metas/ui/web/view/SqlViewEvaluationCtx.java b/src/main/java/de/metas/ui/web/view/ViewEvaluationCtx.java similarity index 70% rename from src/main/java/de/metas/ui/web/view/SqlViewEvaluationCtx.java rename to src/main/java/de/metas/ui/web/view/ViewEvaluationCtx.java index dca921a2b..36aa4a3c3 100644 --- a/src/main/java/de/metas/ui/web/view/SqlViewEvaluationCtx.java +++ b/src/main/java/de/metas/ui/web/view/ViewEvaluationCtx.java @@ -34,20 +34,22 @@ * #L% */ -public class SqlViewEvaluationCtx +public class ViewEvaluationCtx { - public static final SqlViewEvaluationCtx of(final Properties ctx) + public static final ViewEvaluationCtx of(final Properties ctx) { final String adLanguage = Env.getAD_Language(ctx); final UserRolePermissionsKey permissionsKey = UserRolePermissionsKey.of(ctx); - return new SqlViewEvaluationCtx(ctx, adLanguage, permissionsKey); + return new ViewEvaluationCtx(ctx, adLanguage, permissionsKey); } private final Properties ctx; // needed for global context vars private final String adLanguage; private final UserRolePermissionsKey permissionsKey; + + private Evaluatee _evaluatee; // lazy - private SqlViewEvaluationCtx(@NonNull final Properties ctx, @NonNull final String adLanguage, @NonNull final UserRolePermissionsKey permissionsKey) + private ViewEvaluationCtx(@NonNull final Properties ctx, @NonNull final String adLanguage, @NonNull final UserRolePermissionsKey permissionsKey) { this.ctx = ctx; this.adLanguage = adLanguage; @@ -62,7 +64,7 @@ public String toString() .add("permissionsKey", permissionsKey) .toString(); } - + public UserRolePermissionsKey getPermissionsKey() { return permissionsKey; @@ -70,11 +72,19 @@ public UserRolePermissionsKey getPermissionsKey() public Evaluatee toEvaluatee() { - return Evaluatees.mapBuilder() - .put(Env.CTXNAME_AD_Language, adLanguage) - .put(AccessSqlStringExpression.PARAM_UserRolePermissionsKey.getName(), permissionsKey.toPermissionsKeyString()) - .build() - // Fallback to global context - .andComposeWith(Evaluatees.ofCtx(ctx)); + Evaluatee evaluatee = _evaluatee; + + if (evaluatee == null) + { + evaluatee = _evaluatee = Evaluatees.mapBuilder() + .put(Env.CTXNAME_AD_Language, adLanguage) + .put(AccessSqlStringExpression.PARAM_UserRolePermissionsKey.getName(), permissionsKey.toPermissionsKeyString()) + .build() + // Fallback to global context + .andComposeWith(Evaluatees.ofCtx(ctx)); + return evaluatee; + } + + return evaluatee; } } diff --git a/src/main/java/de/metas/ui/web/view/ViewFactory.java b/src/main/java/de/metas/ui/web/view/ViewFactory.java index 963261e45..caae9c336 100644 --- a/src/main/java/de/metas/ui/web/view/ViewFactory.java +++ b/src/main/java/de/metas/ui/web/view/ViewFactory.java @@ -44,6 +44,6 @@ { String windowId(); - /** supported view types (empty means all */ + /** supported view types (empty means all) */ JSONViewDataType[] viewTypes() default {}; } diff --git a/src/main/java/de/metas/ui/web/view/ViewRestController.java b/src/main/java/de/metas/ui/web/view/ViewRestController.java index 33e7cee29..6fb6b404a 100644 --- a/src/main/java/de/metas/ui/web/view/ViewRestController.java +++ b/src/main/java/de/metas/ui/web/view/ViewRestController.java @@ -162,14 +162,12 @@ public JSONViewResult getViewData( } @GetMapping("/layout") - @Deprecated - public JSONViewLayout getViewLayout_DEPRECATED( + public JSONViewLayout getViewLayout( @PathVariable(PARAM_WindowId) final String windowIdStr // , @RequestParam(name = PARAM_ViewDataType, required = true) final JSONViewDataType viewDataType // ) { userSession.assertLoggedIn(); -// userSession.assertDeprecatedRestAPIAllowed(); final WindowId windowId = WindowId.fromJson(windowIdStr); return viewsRepo.getViewLayout(windowId, viewDataType, newJSONOptions()); diff --git a/src/main/java/de/metas/ui/web/view/ViewRowAttributesProviderFactory.java b/src/main/java/de/metas/ui/web/view/ViewRowAttributesProviderFactory.java deleted file mode 100644 index a4fc96ef1..000000000 --- a/src/main/java/de/metas/ui/web/view/ViewRowAttributesProviderFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -package de.metas.ui.web.view; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.adempiere.exceptions.AdempiereException; - -import de.metas.ui.web.window.datatypes.WindowId; -import lombok.NonNull; - -/* - * #%L - * metasfresh-webui-api - * %% - * Copyright (C) 2016 metas GmbH - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ - -public final class ViewRowAttributesProviderFactory -{ - public static final transient ViewRowAttributesProviderFactory instance = new ViewRowAttributesProviderFactory(); - - private final Map> providerClasses = new ConcurrentHashMap<>(); - - private ViewRowAttributesProviderFactory() - { - super(); - } - - public void registerProvider(@NonNull final WindowId windowId, @NonNull final Class providerClass) - { - providerClasses.put(windowId, providerClass); - } - - public IViewRowAttributesProvider createProviderOrNull(final WindowId windowId) - { - final Class providerClass = providerClasses.get(windowId); - if (providerClass == null) - { - return null; - } - - try - { - return providerClass.newInstance(); - } - catch (final Exception e) - { - throw new AdempiereException("Cannot instantiate " + providerClass, e); - } - } -} diff --git a/src/main/java/de/metas/ui/web/view/ViewsRepository.java b/src/main/java/de/metas/ui/web/view/ViewsRepository.java index fe04d07e0..bcf32900c 100644 --- a/src/main/java/de/metas/ui/web/view/ViewsRepository.java +++ b/src/main/java/de/metas/ui/web/view/ViewsRepository.java @@ -31,7 +31,6 @@ import de.metas.ui.web.window.datatypes.WindowId; import de.metas.ui.web.window.datatypes.json.JSONOptions; import de.metas.ui.web.window.descriptor.filters.DocumentFilterDescriptor; -import lombok.NonNull; /* * #%L @@ -89,16 +88,11 @@ public ViewsRepository(final ApplicationContext context) viewTypes = JSONViewDataType.values(); } - registerFactory(windowId, viewTypes, factory); - } - } - - public void registerFactory(final WindowId windowId, final JSONViewDataType[] viewTypes, @NonNull final IViewFactory factory) - { - for (final JSONViewDataType viewType : viewTypes) - { - factories.put(mkFactoryKey(windowId, viewType), factory); - logger.info("Registered {} for windowId={}, viewType={}", factory, windowId, viewTypes); + for (final JSONViewDataType viewType : viewTypes) + { + factories.put(mkFactoryKey(windowId, viewType), factory); + logger.info("Registered {} for windowId={}, viewType={}", factory, windowId, viewTypes); + } } } @@ -129,9 +123,9 @@ public JSONViewLayout getViewLayout(final WindowId windowId, final JSONViewDataT { final IViewFactory factory = getFactory(windowId, viewDataType); final ViewLayout viewLayout = factory.getViewLayout(windowId, viewDataType); - final Collection viewFilters = factory.getViewFilters(windowId, viewDataType); + final Collection viewFilterDescriptors = factory.getViewFilterDescriptors(windowId, viewDataType); - final JSONViewLayout jsonLayout = JSONViewLayout.of(viewLayout, viewFilters, jsonOpts); + final JSONViewLayout jsonLayout = JSONViewLayout.of(viewLayout, viewFilterDescriptors, jsonOpts); // // Enable new record if supported menuTreeRepo.getUserSessionMenuTree() diff --git a/src/main/java/de/metas/ui/web/view/descriptor/SqlViewBinding.java b/src/main/java/de/metas/ui/web/view/descriptor/SqlViewBinding.java index f9d31513b..65d422d69 100644 --- a/src/main/java/de/metas/ui/web/view/descriptor/SqlViewBinding.java +++ b/src/main/java/de/metas/ui/web/view/descriptor/SqlViewBinding.java @@ -15,7 +15,6 @@ import org.adempiere.ad.security.impl.AccessSqlStringExpression; import org.adempiere.util.Check; import org.compiere.util.DB; -import org.compiere.util.Evaluatee; import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; @@ -24,7 +23,7 @@ import com.google.common.collect.ImmutableMap; import de.metas.ui.web.base.model.I_T_WEBUI_ViewSelection; -import de.metas.ui.web.view.SqlViewEvaluationCtx; +import de.metas.ui.web.view.ViewEvaluationCtx; import de.metas.ui.web.view.ViewId; import de.metas.ui.web.view.descriptor.SqlViewRowFieldBinding.SqlViewRowFieldLoader; import de.metas.ui.web.window.datatypes.DocumentId; @@ -85,7 +84,7 @@ public static final Builder builder() private final List rowFieldLoaders; private final ImmutableList defaultOrderBys; - private final DocumentFilterDescriptorsProvider filterDescriptors; + private final DocumentFilterDescriptorsProvider viewFilterDescriptors; private SqlViewBinding(final Builder builder) { @@ -132,7 +131,7 @@ private SqlViewBinding(final Builder builder) this.rowFieldLoaders = ImmutableList.copyOf(rowFieldLoaders); defaultOrderBys = ImmutableList.copyOf(builder.getDefaultOrderBys()); - filterDescriptors = builder.getFilterDescriptors(); + viewFilterDescriptors = builder.getViewFilterDescriptors(); } @Override @@ -284,9 +283,9 @@ public List getRowFieldLoaders() return rowFieldLoaders; } - public DocumentFilterDescriptorsProvider getFilterDescriptors() + public DocumentFilterDescriptorsProvider getViewFilterDescriptors() { - return filterDescriptors; + return viewFilterDescriptors; } public List getDefaultOrderBys() @@ -294,14 +293,12 @@ public List getDefaultOrderBys() return defaultOrderBys; } - public Map getSqlOrderBysIndexedByFieldName(final SqlViewEvaluationCtx viewEvalCtx) + public Map getSqlOrderBysIndexedByFieldName(final ViewEvaluationCtx viewEvalCtx) { - final Evaluatee evalCtx = viewEvalCtx.toEvaluatee(); - final ImmutableMap.Builder sqlOrderBysIndexedByFieldName = ImmutableMap.builder(); for (final SqlViewRowFieldBinding fieldBinding : getFields()) { - final String fieldOrderBy = fieldBinding.getSqlOrderBy().evaluate(evalCtx, OnVariableNotFound.Fail); + final String fieldOrderBy = fieldBinding.getSqlOrderBy().evaluate(viewEvalCtx.toEvaluatee(), OnVariableNotFound.Fail); if (Check.isEmpty(fieldOrderBy, true)) { continue; @@ -350,13 +347,12 @@ public String getSqlCreateSelectionFromSelection() public String getSqlCreateSelectionFrom( // final List sqlParams // - , final SqlViewEvaluationCtx viewEvalCtx // + , final ViewEvaluationCtx viewEvalCtx // , final ViewId newViewId // , final List filters // , final int queryLimit // ) { - final Evaluatee evalCtx = viewEvalCtx.toEvaluatee(); final String sqlTableName = getTableName(); final String sqlTableAlias = getTableAlias(); final String keyColumnNameFQ = getKeyColumnName(); @@ -417,7 +413,7 @@ public String getSqlCreateSelectionFrom( // // // Evaluate the final SQL query - final String sql = sqlBuilder.build().evaluate(evalCtx, OnVariableNotFound.Fail); + final String sql = sqlBuilder.build().evaluate(viewEvalCtx.toEvaluatee(), OnVariableNotFound.Fail); return sql; } @@ -437,7 +433,7 @@ public static final class Builder private SqlViewRowFieldBinding _keyField; private List defaultOrderBys; - private DocumentFilterDescriptorsProvider filterDescriptors = NullDocumentFilterDescriptorsProvider.instance; + private DocumentFilterDescriptorsProvider viewFilterDescriptors = NullDocumentFilterDescriptorsProvider.instance; private Builder() { @@ -519,15 +515,15 @@ private List getDefaultOrderBys() return defaultOrderBys == null ? ImmutableList.of() : defaultOrderBys; } - public Builder setFilterDescriptors(@NonNull final DocumentFilterDescriptorsProvider filterDescriptors) + public Builder setViewFilterDescriptors(@NonNull final DocumentFilterDescriptorsProvider viewFilterDescriptors) { - this.filterDescriptors = filterDescriptors; + this.viewFilterDescriptors = viewFilterDescriptors; return this; } - private DocumentFilterDescriptorsProvider getFilterDescriptors() + private DocumentFilterDescriptorsProvider getViewFilterDescriptors() { - return filterDescriptors; + return viewFilterDescriptors; } } diff --git a/src/main/java/de/metas/ui/web/window/model/DocumentQueryOrderBy.java b/src/main/java/de/metas/ui/web/window/model/DocumentQueryOrderBy.java index 9b0e34da4..ac9f807c5 100644 --- a/src/main/java/de/metas/ui/web/window/model/DocumentQueryOrderBy.java +++ b/src/main/java/de/metas/ui/web/window/model/DocumentQueryOrderBy.java @@ -103,7 +103,6 @@ private DocumentQueryOrderBy(final String fieldName, final boolean ascending) public String toString() { return MoreObjects.toStringHelper(this) - .omitNullValues() .add("fieldName", fieldName) .add("ascending", ascending) .toString();