1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.ui.commons.panels;
20
21 import java.io.Serializable;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.InvocationTargetException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Optional;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.syncope.client.ui.commons.Constants;
29 import org.apache.wicket.Component;
30 import org.apache.wicket.PageReference;
31 import org.apache.wicket.core.util.lang.PropertyResolver;
32 import org.apache.wicket.markup.html.basic.Label;
33 import org.apache.wicket.markup.html.list.ListItem;
34 import org.apache.wicket.markup.html.list.ListView;
35 import org.apache.wicket.markup.html.panel.Panel;
36 import org.apache.wicket.model.ResourceModel;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 public abstract class SimpleListViewPanel<T extends Serializable> extends Panel {
41
42 private static final long serialVersionUID = -7982691107029848579L;
43
44 private static final Logger LOG = LoggerFactory.getLogger(SimpleListViewPanel.class);
45
46 private final ListView<T> beans;
47
48 private final List<T> listOfItems;
49
50
51
52
53
54
55
56
57
58 private SimpleListViewPanel(
59 final String id,
60 final List<T> list,
61 final Class<T> reference,
62 final List<String> includes) {
63
64 super(id);
65 setOutputMarkupId(true);
66
67 final List<String> toBeIncluded;
68 if (includes == null || includes.isEmpty()) {
69 toBeIncluded = new ArrayList<>();
70 for (Field field : reference.getDeclaredFields()) {
71 toBeIncluded.add(field.getName());
72 }
73 } else {
74 toBeIncluded = includes;
75 }
76
77 if (toBeIncluded.isEmpty()) {
78 LOG.warn("No field has been retrieved from {}", reference.getName());
79 listOfItems = new ArrayList<>();
80 } else if (list == null || list.isEmpty()) {
81 LOG.info("No item to be shown");
82 listOfItems = new ArrayList<>();
83 } else {
84 listOfItems = list;
85 LOG.debug("Show fields {}", toBeIncluded);
86 }
87
88 add(header(toBeIncluded));
89
90 beans = new ListView<>("beans", listOfItems) {
91
92 private static final long serialVersionUID = -9112553137618363167L;
93
94 @Override
95 protected void populateItem(final ListItem<T> beanItem) {
96 final T bean = beanItem.getModelObject();
97
98 final ListView<String> fields = new ListView<>("fields", toBeIncluded) {
99
100 private static final long serialVersionUID = -9112553137618363167L;
101
102 @Override
103 protected void populateItem(final ListItem<String> fieldItem) {
104 fieldItem.add(getValueComponent(fieldItem.getModelObject(), bean));
105 }
106 };
107
108 beanItem.add(fields);
109 }
110 };
111 add(beans.setOutputMarkupId(true).setRenderBodyOnly(true));
112 }
113
114 protected ListView<String> header(final List<String> labels) {
115 return new ListView<>("names", labels) {
116
117 private static final long serialVersionUID = -9112553137618363167L;
118
119 @Override
120 protected void populateItem(final ListItem<String> item) {
121 item.add(new Label(Constants.NAME_FIELD_NAME,
122 new ResourceModel(item.getModelObject(), item.getModelObject())));
123 }
124 };
125 }
126
127
128
129
130
131
132 public static class Builder<T extends Serializable> implements Serializable {
133
134 private static final long serialVersionUID = -3643771352897992172L;
135
136 private final List<String> includes = new ArrayList<>();
137
138 private List<T> items;
139
140 private final Class<T> reference;
141
142 private final PageReference pageReference;
143
144 public Builder(final Class<T> reference, final PageReference pageRef) {
145 this.pageReference = pageRef;
146 this.reference = reference;
147 this.items = null;
148 }
149
150
151
152
153
154
155
156 public Builder<T> setItems(final List<T> items) {
157 this.items = items;
158 return this;
159 }
160
161
162
163
164
165
166
167 public Builder<T> addItem(final T item) {
168 if (item == null) {
169 return this;
170 }
171
172 if (this.items == null) {
173 this.items = new ArrayList<>();
174 }
175
176 this.items.add(item);
177 return this;
178 }
179
180
181
182
183
184
185
186 public Builder<T> includes(final String... includes) {
187 for (String include : includes) {
188 if (include != null && !this.includes.contains(include)) {
189 this.includes.add(include);
190 }
191 }
192 return this;
193 }
194
195
196
197
198
199
200
201
202 protected Component getValueComponent(final String key, final T bean) {
203 LOG.debug("Processing field {}", key);
204
205 Object value;
206 try {
207 value = includes.contains(key)
208 ? PropertyResolver.getPropertyGetter(key, bean).invoke(bean)
209 : StringUtils.EMPTY;
210 } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
211 LOG.error("Error retrieving value for field {}", key, e);
212 value = StringUtils.EMPTY;
213 }
214
215 LOG.debug("Field value {}", value);
216
217 return Optional.ofNullable(value)
218 .map(o -> new Label("field", new ResourceModel(o.toString(), o.toString())))
219 .orElseGet(() -> new Label("field", StringUtils.EMPTY));
220 }
221
222 protected T getActualItem(final T item, final List<T> list) {
223 return item == null
224 ? null
225 : list.stream().filter(item::equals).findAny().orElse(null);
226 }
227
228 public SimpleListViewPanel<T> build(final String id) {
229 return new SimpleListViewPanel<T>(id, items, reference, includes) {
230
231 @Override
232 protected Component getValueComponent(final String key, final T bean) {
233 return Builder.this.getValueComponent(key, bean);
234 }
235
236 @Override
237 protected T getActualItem(final T item, final List<T> list) {
238 return Builder.this.getActualItem(item, list);
239 }
240
241 };
242 }
243
244 }
245
246 protected abstract T getActualItem(T item, List<T> list);
247
248 protected abstract Component getValueComponent(String key, T bean);
249
250 }