Skip to content

Commit

Permalink
MID-6393: Added support for per-panel configuration of data providers
Browse files Browse the repository at this point in the history
  • Loading branch information
tonydamage committed Jun 27, 2022
1 parent 8218e27 commit 7bcd075
Show file tree
Hide file tree
Showing 9 changed files with 466 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.gui.api.registry;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.web.component.data.ContainerValueDataProviderFactory;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GuiListDataProviderType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GuiObjectListViewType;

/**
*
* Data Provider registry for customizable data providers
*
*/
public interface DataProviderRegistry {

/**
* Returns provider factory for supplied data type and configuraitno.
*
* @param <T> Data Type
* @param dataType Data Type
* @param viewConfig View configuration
* @param defaultProvider Configuration type of default provider
* @return null, if no provider matches arguments, if viewport configuration does contain concrete provider configuration returns that provider, otherwise returns default provider.
*/
default <T extends Containerable> ContainerValueDataProviderFactory<T,?> forContainerValue(Class<T> dataType, GuiObjectListViewType viewConfig, Class<? extends GuiListDataProviderType> defaultProvider) {
if (viewConfig != null) {
GuiListDataProviderType providerConfig = viewConfig.getDataProvider();
if (providerConfig != null) {
var maybe = forContainerValue(dataType, providerConfig.getClass());
if (maybe != null) {
return maybe;
}
}

}
return forContainerValue(dataType, defaultProvider);
}

/**
*
* @param <T> Data Type
* @param <C> Configuration Type
* @param dataType Data Type
* @param configurationType Configuration Type
* @return Container Value Data Provider Factory for specified type combination, or null if no provider factory matches
*/
<T extends Containerable, C extends GuiListDataProviderType> ContainerValueDataProviderFactory<T,C> forContainerValue(Class<T> dataType, Class<C> configurationType);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.gui.impl.factory.data;

import java.util.List;

import org.apache.wicket.model.IModel;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerValueWrapper;
import com.evolveum.midpoint.gui.impl.component.search.Search;
import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView;
import com.evolveum.midpoint.prism.Objectable;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.web.component.data.ContainerValueDataProviderFactory;
import com.evolveum.midpoint.web.component.data.ISelectableDataProvider;
import com.evolveum.midpoint.web.component.util.AssignmentListProvider;
import com.evolveum.midpoint.web.session.PageStorage;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.InMemoryAssignmentDataProviderType;

@Component
public class InMemoryAssignmentDataProviderFactory implements ContainerValueDataProviderFactory<AssignmentType, InMemoryAssignmentDataProviderType>{

@Override
public Class<AssignmentType> getDataType() {
return AssignmentType.class;
}

@Override
public Class<InMemoryAssignmentDataProviderType> getConfigurationType() {
return InMemoryAssignmentDataProviderType.class;
}

@Override
public boolean isRepositorySearchEnabled() {
return false;
}

@Override
public ISelectableDataProvider<AssignmentType, PrismContainerValueWrapper<AssignmentType>> create(
org.apache.wicket.Component component, @NotNull IModel<Search<AssignmentType>> search,
IModel<List<PrismContainerValueWrapper<AssignmentType>>> model, Class<? extends Objectable> objectType,
String oid, ItemPath path) {
return new AssignmentListProvider(component, search, model);
}

@Override
public ISelectableDataProvider<AssignmentType, PrismContainerValueWrapper<AssignmentType>> create(
org.apache.wicket.Component component, @NotNull IModel<Search<AssignmentType>> search,
IModel<List<PrismContainerValueWrapper<AssignmentType>>> model, Class<? extends Objectable> objectType,
String oid, ItemPath path, CompiledObjectCollectionView collection, Customization<AssignmentType> customization) {
return doCreate(component, search, model, objectType, oid, path, collection, customization);
}

/**
* Static method is neccessary to not serialize also factory
*/
private static ISelectableDataProvider<AssignmentType, PrismContainerValueWrapper<AssignmentType>> doCreate(
org.apache.wicket.Component component, @NotNull IModel<Search<AssignmentType>> search,
IModel<List<PrismContainerValueWrapper<AssignmentType>>> model, Class<? extends Objectable> objectType,
String oid, ItemPath path, CompiledObjectCollectionView collection, Customization<AssignmentType> customization) {
var provider = new AssignmentListProvider(component, search, model) {

@Override
protected PageStorage getPageStorage() {
return customization.getPageStorage();
}

@Override
protected List<PrismContainerValueWrapper<AssignmentType>> postFilter(
List<PrismContainerValueWrapper<AssignmentType>> assignmentList) {
return customization.postFilter(assignmentList);
}

@Override
protected ObjectQuery getCustomizeContentQuery() {
return customization.getCustomizeContentQuery();
}
};
provider.setCompiledObjectCollectionView(collection);
return provider;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (C) 2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.gui.impl.factory.data;

import java.util.List;

import org.apache.wicket.model.IModel;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerValueWrapper;
import com.evolveum.midpoint.gui.impl.component.search.Search;
import com.evolveum.midpoint.model.api.authentication.CompiledObjectCollectionView;
import com.evolveum.midpoint.prism.Objectable;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.web.component.data.ContainerValueDataProviderFactory;
import com.evolveum.midpoint.web.component.data.ISelectableDataProvider;
import com.evolveum.midpoint.web.component.util.RepoAssignmentListProvider;
import com.evolveum.midpoint.web.session.PageStorage;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RepositoryAssignmentDataProviderType;

@Component
public class RepositoryAssignmentDataProviderFactory implements ContainerValueDataProviderFactory<AssignmentType, RepositoryAssignmentDataProviderType>{

@Override
public Class<AssignmentType> getDataType() {
return AssignmentType.class;
}

@Override
public Class<RepositoryAssignmentDataProviderType> getConfigurationType() {
return RepositoryAssignmentDataProviderType.class;
}

@Override
public boolean isRepositorySearchEnabled() {
return true;
}

@Override
public ISelectableDataProvider<AssignmentType, PrismContainerValueWrapper<AssignmentType>> create(
org.apache.wicket.Component component, @NotNull IModel<Search<AssignmentType>> search,
IModel<List<PrismContainerValueWrapper<AssignmentType>>> model, Class<? extends Objectable> objectType,
String oid, ItemPath path) {
return new RepoAssignmentListProvider(component, search, model, objectType, oid, path);
}

@Override
public ISelectableDataProvider<AssignmentType, PrismContainerValueWrapper<AssignmentType>> create(
org.apache.wicket.Component component, @NotNull IModel<Search<AssignmentType>> search,
IModel<List<PrismContainerValueWrapper<AssignmentType>>> model, Class<? extends Objectable> objectType,
String oid, ItemPath path, CompiledObjectCollectionView collection, Customization<AssignmentType> customization) {
return doCreate(component, search, model, objectType, oid, path, collection, customization);
}

private static ISelectableDataProvider<AssignmentType, PrismContainerValueWrapper<AssignmentType>> doCreate(
org.apache.wicket.Component component, @NotNull IModel<Search<AssignmentType>> search,
IModel<List<PrismContainerValueWrapper<AssignmentType>>> model, Class<? extends Objectable> objectType,
String oid, ItemPath path, CompiledObjectCollectionView collection, Customization<AssignmentType> customization) {
RepoAssignmentListProvider provider = new RepoAssignmentListProvider(component, search, model, objectType, oid, path) {

@Override
protected PageStorage getPageStorage() {
return customization.getPageStorage();
}

@Override
protected List<PrismContainerValueWrapper<AssignmentType>> postFilter(
List<PrismContainerValueWrapper<AssignmentType>> assignmentList) {
return customization.postFilter(assignmentList);
}

@Override
protected ObjectQuery getCustomizeContentQuery() {
return customization.getCustomizeContentQuery();
}
};
provider.setCompiledObjectCollectionView(collection);
return provider;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import com.evolveum.midpoint.web.component.AjaxIconButton;
import com.evolveum.midpoint.web.component.assignment.AssignmentPanel;
import com.evolveum.midpoint.web.component.assignment.AssignmentsUtil;
import com.evolveum.midpoint.web.component.data.ContainerValueDataProviderFactory;
import com.evolveum.midpoint.web.component.data.ISelectableDataProvider;
import com.evolveum.midpoint.web.component.data.column.AjaxLinkColumn;
import com.evolveum.midpoint.web.component.data.column.CheckBoxHeaderColumn;
Expand Down Expand Up @@ -116,7 +117,7 @@ protected boolean isCreateNewObjectVisible() {
}

protected boolean isRepositorySearchEnabled() {
return getPageBase().getCompiledGuiProfile().isUseRepositoryAssignmentSearch();
return providerFactory().isRepositorySearchEnabled();
}

@Override
Expand Down Expand Up @@ -547,57 +548,34 @@ public void deleteItemPerformed(AjaxRequestTarget target, List<PrismContainerVal
super.deleteItemPerformed(target, toDeleteList);
}

protected ContainerValueDataProviderFactory<AssignmentType, ?> providerFactory() {
return getPageBase().getDataProviderRegistry().forContainerValue(AssignmentType.class, this.getPanelConfiguration().getListView(), InMemoryAssignmentDataProviderType.class);
}

@Override
protected ISelectableDataProvider<AssignmentType, PrismContainerValueWrapper<AssignmentType>> createProvider() {
var searchModel = getSearchModel();
var assignments = loadValuesModel();
return isRepositorySearchEnabled() ? createRepositoryProvider(searchModel, assignments) : createInMemoryProvider(searchModel, assignments);
}

protected AssignmentListProvider createInMemoryProvider(IModel<Search<AssignmentType>> searchModel, IModel<List<PrismContainerValueWrapper<AssignmentType>>> assignments) {
var provider = new AssignmentListProvider(AbstractAssignmentTypePanel.this, searchModel, assignments) {

@Override
protected PageStorage getPageStorage() {
return AbstractAssignmentTypePanel.this.getPageStorage();
}

@Override
protected List<PrismContainerValueWrapper<AssignmentType>> postFilter(List<PrismContainerValueWrapper<AssignmentType>> assignmentList) {
return customPostSearch(assignmentList);
}

@Override
protected ObjectQuery getCustomizeContentQuery() {
return AbstractAssignmentTypePanel.this.getCustomizeQuery();
}
};
provider.setCompiledObjectCollectionView(getObjectCollectionView());
return provider;
}

protected RepoAssignmentListProvider createRepositoryProvider(IModel<Search<AssignmentType>> searchModel, IModel<List<PrismContainerValueWrapper<AssignmentType>>> assignments) {

var itemPath = model.getObject().getPath();
var assignmentListProvider = new RepoAssignmentListProvider(AbstractAssignmentTypePanel.this, searchModel, assignments, objectType, objectOid, itemPath) {
return providerFactory().create(AbstractAssignmentTypePanel.this, searchModel, assignments, objectType, objectOid, itemPath, getObjectCollectionView(), new ContainerValueDataProviderFactory.Customization<AssignmentType>() {

private static final long serialVersionUID = 1L;

@Override
protected PageStorage getPageStorage() {
public PageStorage getPageStorage() {
return AbstractAssignmentTypePanel.this.getPageStorage();
}

@Override
protected List<PrismContainerValueWrapper<AssignmentType>> postFilter(List<PrismContainerValueWrapper<AssignmentType>> assignmentList) {
public List<PrismContainerValueWrapper<AssignmentType>> postFilter(List<PrismContainerValueWrapper<AssignmentType>> assignmentList) {
return customPostSearch(assignmentList);
}

@Override
protected ObjectQuery getCustomizeContentQuery() {
public ObjectQuery getCustomizeContentQuery() {
return AbstractAssignmentTypePanel.this.getCustomizeQuery();
}
};
assignmentListProvider.setCompiledObjectCollectionView(getObjectCollectionView());
return assignmentListProvider;
});
}

protected IModel<List<PrismContainerValueWrapper<AssignmentType>>> loadValuesModel() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.gui.impl.registry;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.gui.api.registry.DataProviderRegistry;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.web.component.data.ContainerValueDataProviderFactory;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GuiListDataProviderType;

/**
*
* Spring based Data Provider registry
*
* Factories are expected to be instantiated by Spring using {@link Component} annotation
* and autowired using {@link Autowired}
*
*/
@Component
public class DataProviderRegistryImpl implements DataProviderRegistry {

@Autowired
List<ContainerValueDataProviderFactory<?,?>> containerValueFactories;

@Override
public <T extends Containerable, C extends GuiListDataProviderType> ContainerValueDataProviderFactory<T, C> forContainerValue(
Class<T> dataType, Class<C> configurationType) {
for (ContainerValueDataProviderFactory<?, ?> factory : containerValueFactories) {
if (factory.getConfigurationType().isAssignableFrom(configurationType) && factory.isSupported(dataType)) {
return factory.specializedFor(dataType, configurationType);
}
}
return null;
}
}

0 comments on commit 7bcd075

Please sign in to comment.