[SYNCOPE-1262] Last matrix parameter still there
[syncope.git] / client / console / src / main / java / org / apache / syncope / client / console / reports / ReportletDirectoryPanel.java
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.syncope.client.console.reports;
20
21 import com.fasterxml.jackson.databind.ObjectMapper;
22 import java.io.Serializable;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.stream.Collectors;
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.syncope.client.console.SyncopeConsoleSession;
31 import org.apache.syncope.client.console.commons.Constants;
32 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
33 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
34 import org.apache.syncope.client.console.pages.BasePage;
35 import org.apache.syncope.client.console.panels.DirectoryPanel;
36 import org.apache.syncope.client.console.panels.ModalPanel;
37 import org.apache.syncope.client.console.rest.ImplementationRestClient;
38 import org.apache.syncope.client.console.rest.ReportRestClient;
39 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
40 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
41 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
42 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
43 import org.apache.syncope.client.console.wizards.AjaxWizard;
44 import org.apache.syncope.common.lib.types.StandardEntitlement;
45 import org.apache.syncope.common.lib.SyncopeClientException;
46 import org.apache.syncope.common.lib.report.ReportletConf;
47 import org.apache.syncope.common.lib.to.ImplementationTO;
48 import org.apache.syncope.common.lib.to.ReportTO;
49 import org.apache.syncope.common.lib.types.ImplementationEngine;
50 import org.apache.syncope.common.lib.types.ImplementationType;
51 import org.apache.wicket.PageReference;
52 import org.apache.wicket.ajax.AjaxRequestTarget;
53 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
54 import org.apache.wicket.event.Broadcast;
55 import org.apache.wicket.event.IEvent;
56 import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
57 import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
58 import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
59 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
60 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
61 import org.apache.wicket.markup.html.basic.Label;
62 import org.apache.wicket.markup.repeater.Item;
63 import org.apache.wicket.model.CompoundPropertyModel;
64 import org.apache.wicket.model.IModel;
65 import org.apache.wicket.model.StringResourceModel;
66
67 /**
68 * Reportlets page.
69 */
70 public class ReportletDirectoryPanel extends DirectoryPanel<
71 ReportletWrapper, ReportletWrapper, DirectoryDataProvider<ReportletWrapper>, ReportRestClient>
72 implements ModalPanel {
73
74 private static final long serialVersionUID = 4984337552918213290L;
75
76 private static final ObjectMapper MAPPER = new ObjectMapper();
77
78 private final BaseModal<ReportTO> baseModal;
79
80 private final String report;
81
82 public ReportletDirectoryPanel(
83 final BaseModal<ReportTO> baseModal, final String report, final PageReference pageRef) {
84 super(BaseModal.CONTENT_ID, pageRef, false);
85
86 disableCheckBoxes();
87
88 this.baseModal = baseModal;
89 this.report = report;
90 this.restClient = new ReportRestClient();
91
92 enableExitButton();
93
94 this.addNewItemPanelBuilder(
95 new ReportletWizardBuilder(report, new ReportletWrapper(true), pageRef), true);
96
97 MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, StandardEntitlement.REPORT_UPDATE);
98 initResultTable();
99 }
100
101 @Override
102 protected List<IColumn<ReportletWrapper, String>> getColumns() {
103 final List<IColumn<ReportletWrapper, String>> columns = new ArrayList<>();
104
105 columns.add(new PropertyColumn<>(
106 new StringResourceModel("reportlet", this), "implementationKey", "implementationKey"));
107
108 columns.add(new AbstractColumn<ReportletWrapper, String>(
109 new StringResourceModel("configuration", this)) {
110
111 private static final long serialVersionUID = -4008579357070833846L;
112
113 @Override
114 public void populateItem(
115 final Item<ICellPopulator<ReportletWrapper>> cellItem,
116 final String componentId,
117 final IModel<ReportletWrapper> rowModel) {
118
119 if (rowModel.getObject().getConf() == null) {
120 cellItem.add(new Label(componentId, ""));
121 } else {
122 cellItem.add(new Label(componentId, rowModel.getObject().getConf().getClass().getName()));
123 }
124 }
125 });
126
127 return columns;
128 }
129
130 @Override
131 public ActionsPanel<ReportletWrapper> getActions(final IModel<ReportletWrapper> model) {
132 final ActionsPanel<ReportletWrapper> panel = super.getActions(model);
133
134 panel.add(new ActionLink<ReportletWrapper>() {
135
136 private static final long serialVersionUID = -3722207913631435501L;
137
138 @Override
139 public void onClick(final AjaxRequestTarget target, final ReportletWrapper ignore) {
140 ReportletDirectoryPanel.this.getTogglePanel().close(target);
141 if (model.getObject().getConf() == null) {
142 SyncopeConsoleSession.get().info(getString("noConf"));
143 } else {
144 send(ReportletDirectoryPanel.this, Broadcast.EXACT,
145 new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
146 }
147 }
148 }, ActionLink.ActionType.EDIT, StandardEntitlement.REPORT_UPDATE);
149 panel.add(new ActionLink<ReportletWrapper>() {
150
151 private static final long serialVersionUID = -3722207913631435501L;
152
153 @Override
154 public void onClick(final AjaxRequestTarget target, final ReportletWrapper ignore) {
155 final ReportletConf reportlet = model.getObject().getConf();
156 try {
157 final ReportTO actual = restClient.read(report);
158 actual.getReportlets().remove(model.getObject().getImplementationKey());
159 restClient.update(actual);
160
161 SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
162 customActionOnFinishCallback(target);
163 } catch (SyncopeClientException e) {
164 LOG.error("While deleting {}", reportlet.getName(), e);
165 SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
166 ? e.getClass().getName() : e.getMessage());
167 }
168 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
169 }
170 }, ActionLink.ActionType.DELETE, StandardEntitlement.REPORT_DELETE, true);
171
172 return panel;
173 }
174
175 @Override
176 public ActionsPanel<Serializable> getHeader(final String componentId) {
177 final ActionsPanel<Serializable> panel = new ActionsPanel<>(componentId, null);
178
179 panel.add(new ActionLink<Serializable>() {
180
181 private static final long serialVersionUID = -7978723352517770644L;
182
183 @Override
184 public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
185 if (target != null) {
186 customActionOnFinishCallback(target);
187 }
188 }
189 }, ActionLink.ActionType.RELOAD, StandardEntitlement.TASK_LIST).hideLabel();
190 return panel;
191 }
192
193 @Override
194 protected Collection<ActionType> getBulkActions() {
195 final List<ActionType> bulkActions = new ArrayList<>();
196 bulkActions.add(ActionType.DELETE);
197 return bulkActions;
198 }
199
200 @Override
201 protected ReportDataProvider dataProvider() {
202 return new ReportDataProvider(rows);
203 }
204
205 @Override
206 protected String paginatorRowsKey() {
207 return Constants.PREF_REPORTLET_TASKS_PAGINATOR_ROWS;
208 }
209
210 protected class ReportDataProvider extends DirectoryDataProvider<ReportletWrapper> {
211
212 private static final long serialVersionUID = 4725679400450513556L;
213
214 private final ImplementationRestClient implementationClient = new ImplementationRestClient();
215
216 private final SortableDataProviderComparator<ReportletWrapper> comparator;
217
218 public ReportDataProvider(final int paginatorRows) {
219 super(paginatorRows);
220
221 //Default sorting
222 setSort("implementationKey", SortOrder.ASCENDING);
223 comparator = new SortableDataProviderComparator<>(this);
224 }
225
226 private List<ReportletWrapper> getReportletWrappers(final ReportTO reportTO) {
227 return reportTO.getReportlets().stream().map(reportlet -> {
228 ImplementationTO impl = implementationClient.read(ImplementationType.REPORTLET, reportlet);
229
230 ReportletWrapper wrapper = new ReportletWrapper(false).
231 setImplementationKey(impl.getKey()).
232 setImplementationEngine(impl.getEngine());
233 if (impl.getEngine() == ImplementationEngine.JAVA) {
234 try {
235 ReportletConf reportletConf = MAPPER.readValue(impl.getBody(), ReportletConf.class);
236 wrapper.setConf(reportletConf);
237 } catch (Exception e) {
238 LOG.error("During deserialization", e);
239 }
240 }
241
242 return wrapper;
243 }).filter(wrapper -> wrapper != null).collect(Collectors.toList());
244 }
245
246 @Override
247 public Iterator<ReportletWrapper> iterator(final long first, final long count) {
248 final ReportTO actual = restClient.read(report);
249
250 List<ReportletWrapper> reportlets = getReportletWrappers(actual);
251
252 Collections.sort(reportlets, comparator);
253 return reportlets.subList((int) first, (int) (first + count)).iterator();
254 }
255
256 @Override
257 public long size() {
258 final ReportTO actual = restClient.read(report);
259 return getReportletWrappers(actual).size();
260 }
261
262 @Override
263 public IModel<ReportletWrapper> model(final ReportletWrapper object) {
264 return new CompoundPropertyModel<>(object);
265 }
266 }
267
268 @Override
269 public void onEvent(final IEvent<?> event) {
270 super.onEvent(event);
271 if (event.getPayload() instanceof ExitEvent && modal != null) {
272 final AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget();
273 baseModal.show(false);
274 baseModal.close(target);
275 }
276 }
277 }