1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.field.factory;
35
36 import info.magnolia.objectfactory.ComponentProvider;
37 import info.magnolia.ui.field.AbstractSelectFieldDefinition;
38 import info.magnolia.ui.field.SelectFieldSupport;
39 import info.magnolia.ui.framework.datasource.definition.DatasourceDefinition;
40
41 import java.lang.reflect.InvocationTargetException;
42 import java.lang.reflect.Method;
43 import java.util.function.Consumer;
44 import java.util.function.Predicate;
45 import java.util.stream.Stream;
46
47 import javax.inject.Inject;
48
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 import com.vaadin.data.HasDataProvider;
53 import com.vaadin.data.HasFilterableDataProvider;
54 import com.vaadin.data.HasValue;
55 import com.vaadin.data.provider.DataProvider;
56 import com.vaadin.data.provider.DataProviderWrapper;
57 import com.vaadin.data.provider.Query;
58 import com.vaadin.ui.AbstractListing;
59 import com.vaadin.ui.IconGenerator;
60 import com.vaadin.ui.ItemCaptionGenerator;
61
62
63
64
65
66
67
68 public abstract class AbstractSelectFieldFactory<D extends AbstractSelectFieldDefinition<T, DatasourceDefinition>, T> extends AbstractFieldFactory<T, D> {
69
70 protected static final Logger log = LoggerFactory.getLogger(AbstractSelectFieldFactory.class);
71
72 private final SelectFieldSupport<T> selectFieldSupport;
73
74 @Inject
75 public AbstractSelectFieldFactory(D definition, ComponentProvider componentProvider, SelectFieldSupport<T> selectFieldSupport) {
76 super(definition, componentProvider);
77 this.selectFieldSupport = selectFieldSupport;
78 }
79
80 @Override
81 public HasValue<T> createField() {
82 HasValue<T> selectField = super.createField();
83
84 if (selectField instanceof HasDataProvider) {
85 ((HasDataProvider<T>) selectField).setDataProvider(getDataProvider());
86 }
87
88 if (selectField instanceof HasFilterableDataProvider) {
89 ((HasFilterableDataProvider) selectField).setDataProvider(getDataProvider());
90 }
91
92 if (selectField instanceof AbstractListing) {
93 accessGeneratorSetter("setItemCaptionGenerator", ItemCaptionGenerator.class, selectField).accept(getCaptionGenerator());
94 accessGeneratorSetter("setItemIconGenerator", IconGenerator.class, selectField).accept(selectFieldSupport.getIconGenerator());
95 }
96
97 return selectField;
98 }
99
100 protected ItemCaptionGenerator<T> getCaptionGenerator() {
101 return selectFieldSupport.getItemCaptionGenerator();
102 }
103
104 protected DataProvider<T, ?> getDataProvider() {
105 final DataProvider wrappedDataProvider = this.selectFieldSupport.getDataProvider();
106 return new DataProviderWrapper<T, String, Object>(wrappedDataProvider) {
107 @Override
108 protected Object getFilter(Query<T, String> query) {
109 return null;
110 }
111
112 @Override
113 public Stream<T> fetch(Query<T, String> t) {
114 return super.fetch(t).filter(getFilterPredicate(t));
115 }
116
117 @Override
118 public int size(Query<T, String> t) {
119 return (int) fetch(t).count();
120 }
121
122 private Predicate<T> getFilterPredicate(Query<T, String> t) {
123 switch (getDefinition().getFilteringMode()) {
124 case CONTAINS:
125 return item -> getCaptionGenerator().apply(item).contains(t.getFilter().orElse(""));
126 case STARTSWITH:
127 return item -> getCaptionGenerator().apply(item).startsWith(t.getFilter().orElse(""));
128 default:
129 return anEnum -> true;
130 }
131 }
132 };
133 }
134
135
136
137 private <GENERATOR> Consumer<GENERATOR> accessGeneratorSetter(String methodName, Class<GENERATOR> argType, Object field) {
138 try {
139 final Method method = field.getClass().getMethod(methodName, argType);
140 method.setAccessible(true);
141 return generator -> {
142 try {
143 method.invoke(field, generator);
144 } catch (IllegalAccessException | InvocationTargetException e) {
145 log.error("An error occurred while trying to invoke method", e);
146 }
147 };
148 } catch (NoSuchMethodException e) {
149 return generator -> {
150 };
151 } catch (Exception e) {
152 throw new RuntimeException("An error occurred while trying to access method", e);
153 }
154 }
155 }