1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.console.reports;
20
21 import com.fasterxml.jackson.databind.json.JsonMapper;
22 import java.io.Serializable;
23 import java.util.List;
24 import java.util.Optional;
25 import org.apache.syncope.client.console.SyncopeWebApplication;
26 import org.apache.syncope.client.console.panels.BeanPanel;
27 import org.apache.syncope.client.console.panels.search.SearchUtils;
28 import org.apache.syncope.client.console.rest.ImplementationRestClient;
29 import org.apache.syncope.client.console.rest.ReportRestClient;
30 import org.apache.syncope.client.console.tasks.CrontabPanel;
31 import org.apache.syncope.client.console.wizards.BaseAjaxWizardBuilder;
32 import org.apache.syncope.client.ui.commons.Constants;
33 import org.apache.syncope.client.ui.commons.MIMETypesLoader;
34 import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
35 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
36 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
37 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
38 import org.apache.syncope.common.lib.report.ReportConf;
39 import org.apache.syncope.common.lib.to.ImplementationTO;
40 import org.apache.syncope.common.lib.to.ReportTO;
41 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
42 import org.apache.syncope.common.lib.types.ImplementationEngine;
43 import org.apache.wicket.PageReference;
44 import org.apache.wicket.WicketRuntimeException;
45 import org.apache.wicket.ajax.AjaxRequestTarget;
46 import org.apache.wicket.extensions.wizard.WizardModel;
47 import org.apache.wicket.extensions.wizard.WizardStep;
48 import org.apache.wicket.markup.html.basic.Label;
49 import org.apache.wicket.model.IModel;
50 import org.apache.wicket.model.Model;
51 import org.apache.wicket.model.PropertyModel;
52 import org.springframework.beans.BeanWrapper;
53 import org.springframework.beans.PropertyAccessorFactory;
54
55 public class ReportWizardBuilder extends BaseAjaxWizardBuilder<ReportTO> {
56
57 private static final long serialVersionUID = 5945391813567245081L;
58
59 protected static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
60
61 protected final ImplementationRestClient implementationRestClient;
62
63 protected final ReportRestClient reportRestClient;
64
65 protected final MIMETypesLoader mimeTypesLoader;
66
67 protected final Model<ReportConfWrapper> conf = new Model<>();
68
69 protected CrontabPanel crontabPanel;
70
71 public ReportWizardBuilder(
72 final ReportTO reportTO,
73 final ImplementationRestClient implementationRestClient,
74 final ReportRestClient reportRestClient,
75 final MIMETypesLoader mimeTypesLoader,
76 final PageReference pageRef) {
77
78 super(reportTO, pageRef);
79
80 this.implementationRestClient = implementationRestClient;
81 this.reportRestClient = reportRestClient;
82 this.mimeTypesLoader = mimeTypesLoader;
83 }
84
85 @Override
86 protected Serializable onApplyInternal(final ReportTO modelObject) {
87 if (conf.getObject() != null) {
88 try {
89 ImplementationTO implementation = implementationRestClient.read(
90 IdRepoImplementationType.REPORT_DELEGATE, modelObject.getJobDelegate());
91 if (implementation.getEngine() == ImplementationEngine.JAVA) {
92 BeanWrapper confWrapper = PropertyAccessorFactory.forBeanPropertyAccess(conf.getObject().getConf());
93 conf.getObject().getSCondWrapper().forEach((fieldName, pair) -> confWrapper.setPropertyValue(
94 fieldName, SearchUtils.buildFIQL(pair.getRight(), pair.getLeft())));
95
96 implementation.setBody(MAPPER.writeValueAsString(conf.getObject().getConf()));
97 implementationRestClient.update(implementation);
98 }
99 } catch (Exception e) {
100 throw new WicketRuntimeException(e);
101 }
102 }
103
104 modelObject.setCronExpression(crontabPanel.getCronExpression());
105
106 if (modelObject.getKey() == null) {
107 reportRestClient.create(modelObject);
108 } else {
109 reportRestClient.update(modelObject);
110 }
111
112 return modelObject;
113 }
114
115 protected void setConf(final String jobDelegate) {
116 try {
117 ImplementationTO implementation = implementationRestClient.read(
118 IdRepoImplementationType.REPORT_DELEGATE, jobDelegate);
119 if (implementation.getEngine() == ImplementationEngine.JAVA) {
120 conf.setObject(new ReportConfWrapper());
121 conf.getObject().setConf(MAPPER.readValue(implementation.getBody(), ReportConf.class));
122 } else {
123 conf.setObject(null);
124 }
125 } catch (Exception e) {
126 LOG.error("Could not read or parse {}", jobDelegate, e);
127 }
128 }
129
130 @Override
131 protected WizardModel buildModelSteps(final ReportTO modelObject, final WizardModel wizardModel) {
132 Optional.ofNullable(modelObject.getJobDelegate()).ifPresent(this::setConf);
133
134 Configuration configuration = new Configuration();
135 wizardModel.add(new Profile(modelObject, configuration));
136 wizardModel.add(configuration);
137 wizardModel.add(new Schedule(modelObject));
138 return wizardModel;
139 }
140
141 public class Profile extends WizardStep {
142
143 private static final long serialVersionUID = -3043839139187792810L;
144
145 private final IModel<List<String>> reportJobDelegates = SyncopeWebApplication.get().
146 getImplementationInfoProvider().getReportJobDelegates();
147
148 public Profile(final ReportTO modelObject, final Configuration configuration) {
149 AjaxTextFieldPanel name = new AjaxTextFieldPanel(
150 Constants.NAME_FIELD_NAME, Constants.NAME_FIELD_NAME,
151 new PropertyModel<>(modelObject, Constants.NAME_FIELD_NAME), false);
152 add(name.addRequiredLabel().setEnabled(true));
153
154 AjaxCheckBoxPanel active = new AjaxCheckBoxPanel(
155 "active", "active", new PropertyModel<>(modelObject, "active"), false);
156 add(active);
157
158 AjaxTextFieldPanel mimeType = new AjaxTextFieldPanel(
159 "mimeType", "mimeType", new PropertyModel<>(modelObject, "mimeType"));
160 mimeType.setChoices(mimeTypesLoader.getMimeTypes());
161 add(mimeType.addRequiredLabel());
162
163 AjaxTextFieldPanel fileExt = new AjaxTextFieldPanel(
164 "fileExt", "fileExt", new PropertyModel<>(modelObject, "fileExt"));
165 add(fileExt.addRequiredLabel());
166 mimeType.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
167
168 private static final long serialVersionUID = -6139318907146065915L;
169
170 @Override
171 protected void onUpdate(final AjaxRequestTarget target) {
172 Optional.ofNullable(mimeTypesLoader.getFileExt(mimeType.getModelObject())).
173 ifPresent(fileExt::setModelObject);
174 target.add(fileExt);
175 }
176 });
177
178 AjaxDropDownChoicePanel<String> jobDelegate = new AjaxDropDownChoicePanel<>(
179 "jobDelegate", "jobDelegate", new PropertyModel<>(modelObject, "jobDelegate"), false);
180 jobDelegate.setChoices(reportJobDelegates.getObject());
181 add(jobDelegate.addRequiredLabel().setEnabled(modelObject.getKey() == null));
182 jobDelegate.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
183
184 private static final long serialVersionUID = -6139318907146065915L;
185
186 @Override
187 protected void onUpdate(final AjaxRequestTarget target) {
188 setConf(jobDelegate.getModelObject());
189 configuration.update();
190 }
191 });
192 }
193 }
194
195 public class Configuration extends WizardStep implements WizardModel.ICondition {
196
197 private static final long serialVersionUID = -785981096328637758L;
198
199 public Configuration() {
200 update();
201 }
202
203 protected void update() {
204 if (conf.getObject() == null) {
205 addOrReplace(new Label("bean", Model.of()));
206 } else {
207 addOrReplace(new BeanPanel<>(
208 "bean",
209 new PropertyModel<>(conf.getObject(), "conf"),
210 conf.getObject().getSCondWrapper(),
211 pageRef).
212 setRenderBodyOnly(true));
213 }
214 }
215
216 @Override
217 public boolean evaluate() {
218 return conf.getObject() != null;
219 }
220 }
221
222 public class Schedule extends WizardStep {
223
224 private static final long serialVersionUID = -785981096328637758L;
225
226 public Schedule(final ReportTO modelObject) {
227 crontabPanel = new CrontabPanel(
228 "schedule", new PropertyModel<>(modelObject, "cronExpression"), modelObject.getCronExpression());
229 add(crontabPanel);
230 }
231 }
232 }