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.tasks;
20
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Optional;
25 import java.util.regex.Pattern;
26 import java.util.regex.PatternSyntaxException;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.syncope.client.console.SyncopeConsoleSession;
29 import org.apache.syncope.client.console.panels.AbstractModalPanel;
30 import org.apache.syncope.client.console.rest.TaskRestClient;
31 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
32 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
33 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
34 import org.apache.syncope.client.ui.commons.Constants;
35 import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
36 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
37 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
38 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxGridFieldPanel;
39 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
40 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
41 import org.apache.syncope.common.lib.form.FormPropertyType;
42 import org.apache.syncope.common.lib.to.FormPropertyDefTO;
43 import org.apache.syncope.common.lib.to.MacroTaskTO;
44 import org.apache.syncope.common.lib.types.TaskType;
45 import org.apache.wicket.PageReference;
46 import org.apache.wicket.ajax.AjaxRequestTarget;
47 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
48 import org.apache.wicket.markup.html.WebMarkupContainer;
49 import org.apache.wicket.markup.html.list.ListItem;
50 import org.apache.wicket.markup.html.list.ListView;
51 import org.apache.wicket.model.IModel;
52 import org.apache.wicket.model.PropertyModel;
53 import org.apache.wicket.model.util.ListModel;
54 import org.apache.wicket.spring.injection.annot.SpringBean;
55 import org.apache.wicket.validation.IValidatable;
56 import org.apache.wicket.validation.IValidator;
57 import org.apache.wicket.validation.ValidationError;
58
59 public class FormPropertyDefsPanel extends AbstractModalPanel<MacroTaskTO> {
60
61 private static final long serialVersionUID = 6991001927367507753L;
62
63 @SpringBean
64 protected TaskRestClient taskRestClient;
65
66 protected final MacroTaskTO task;
67
68 protected final IModel<List<FormPropertyDefTO>> model;
69
70 public FormPropertyDefsPanel(
71 final MacroTaskTO task,
72 final BaseModal<MacroTaskTO> modal,
73 final PageReference pageRef) {
74
75 super(modal, pageRef);
76 this.task = task;
77
78 WebMarkupContainer propertyDefContainer = new WebMarkupContainer("propertyDefContainer");
79 add(propertyDefContainer.setOutputMarkupId(true));
80
81 model = new ListModel<>(new ArrayList<>());
82 model.getObject().addAll(task.getFormPropertyDefs());
83
84 ListView<FormPropertyDefTO> propertyDefs = new ListView<>("propertyDefs", model) {
85
86 private static final long serialVersionUID = 1814616131938968887L;
87
88 @Override
89 protected void populateItem(final ListItem<FormPropertyDefTO> item) {
90 FormPropertyDefTO fpd = item.getModelObject();
91
92 AjaxTextFieldPanel key = new AjaxTextFieldPanel(
93 "key",
94 "key",
95 new PropertyModel<>(fpd, "key"),
96 true);
97 item.add(key.setRequired(true).hideLabel());
98
99 AjaxTextFieldPanel name = new AjaxTextFieldPanel(
100 "name",
101 "name",
102 new PropertyModel<>(fpd, "name"),
103 true);
104 item.add(name.setRequired(true).hideLabel());
105
106 AjaxCheckBoxPanel readable = new AjaxCheckBoxPanel(
107 "readable",
108 "readable",
109 new PropertyModel<>(fpd, "readable"),
110 true);
111 item.add(readable.hideLabel());
112
113 AjaxCheckBoxPanel writable = new AjaxCheckBoxPanel(
114 "writable",
115 "writable",
116 new PropertyModel<>(fpd, "writable"),
117 true);
118 item.add(writable.hideLabel());
119
120 AjaxCheckBoxPanel required = new AjaxCheckBoxPanel(
121 "required",
122 "required",
123 new PropertyModel<>(fpd, "required"),
124 true);
125 item.add(required.hideLabel());
126
127 AjaxDropDownChoicePanel<FormPropertyType> type = new AjaxDropDownChoicePanel<>(
128 "type",
129 "type",
130 new PropertyModel<>(fpd, "type"),
131 true);
132 type.setChoices(List.of(FormPropertyType.values())).setNullValid(false);
133 item.add(type.setRequired(true).hideLabel());
134
135 AjaxTextFieldPanel stringRegEx = new AjaxTextFieldPanel(
136 "stringRegEx",
137 "stringRegEx",
138 new IModel<String>() {
139
140 private static final long serialVersionUID = 1015030402166681242L;
141
142 @Override
143 public String getObject() {
144 return Optional.ofNullable(fpd.getStringRegEx()).map(Pattern::pattern).orElse(null);
145 }
146
147 @Override
148 public void setObject(final String object) {
149 fpd.setStringRegEx(Optional.ofNullable(object).map(Pattern::compile).orElse(null));
150 }
151 }, true);
152 stringRegEx.getField().add(new IValidator<String>() {
153
154 private static final long serialVersionUID = 3978328825079032964L;
155
156 @Override
157 public void validate(final IValidatable<String> validatable) {
158 try {
159 Pattern.compile(validatable.getValue());
160 } catch (PatternSyntaxException e) {
161 validatable.error(new ValidationError(fpd.getKey() + ": invalid RegEx"));
162 }
163 }
164 });
165 stringRegEx.setVisible(fpd.getType() == FormPropertyType.String);
166 item.add(stringRegEx.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
167
168 AjaxTextFieldPanel datePattern = new AjaxTextFieldPanel(
169 "datePattern",
170 "datePattern",
171 new PropertyModel<>(fpd, "datePattern"),
172 true);
173 datePattern.setVisible(fpd.getType() == FormPropertyType.Date);
174 item.add(datePattern.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
175
176 AjaxGridFieldPanel<String, String, String> enumValues = new AjaxGridFieldPanel<>(
177 "enumValues",
178 "enumValues",
179 new PropertyModel<>(fpd, "enumValues"));
180 enumValues.setVisible(fpd.getType() == FormPropertyType.Enum);
181 item.add(enumValues.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
182
183 WebMarkupContainer dropdownConf = new WebMarkupContainer("dropdownConf");
184 dropdownConf.setVisible(fpd.getType() == FormPropertyType.Dropdown);
185 item.add(dropdownConf.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
186 AjaxCheckBoxPanel dropdownSingleSelection = new AjaxCheckBoxPanel(
187 "dropdownSingleSelection",
188 "dropdownSingleSelection",
189 new PropertyModel<>(fpd, "dropdownSingleSelection"),
190 true);
191 dropdownConf.add(dropdownSingleSelection.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
192 AjaxCheckBoxPanel dropdownFreeForm = new AjaxCheckBoxPanel(
193 "dropdownFreeForm",
194 "dropdownFreeForm",
195 new PropertyModel<>(fpd, "dropdownFreeForm"),
196 true);
197 dropdownConf.add(dropdownFreeForm.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
198
199 type.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
200
201 private static final long serialVersionUID = -1107858522700306810L;
202
203 @Override
204 protected void onUpdate(final AjaxRequestTarget target) {
205 switch (type.getModelObject()) {
206 case String:
207 stringRegEx.setVisible(true);
208 datePattern.setVisible(false);
209 enumValues.setVisible(false);
210 fpd.getEnumValues().clear();
211 dropdownConf.setVisible(false);
212 break;
213
214 case Date:
215 stringRegEx.setVisible(false);
216 fpd.setStringRegEx(null);
217 datePattern.setVisible(true);
218 enumValues.setVisible(false);
219 fpd.getEnumValues().clear();
220 dropdownConf.setVisible(false);
221 break;
222
223 case Enum:
224 stringRegEx.setVisible(false);
225 fpd.setStringRegEx(null);
226 datePattern.setVisible(false);
227 enumValues.setVisible(true);
228 dropdownConf.setVisible(false);
229 break;
230
231 case Dropdown:
232 stringRegEx.setVisible(false);
233 fpd.setStringRegEx(null);
234 datePattern.setVisible(false);
235 enumValues.setVisible(false);
236 fpd.getEnumValues().clear();
237 dropdownConf.setVisible(true);
238 break;
239
240 default:
241 stringRegEx.setVisible(false);
242 fpd.setStringRegEx(null);
243 datePattern.setVisible(false);
244 enumValues.setVisible(false);
245 fpd.getEnumValues().clear();
246 dropdownConf.setVisible(false);
247 }
248
249 target.add(stringRegEx);
250 target.add(datePattern);
251 target.add(enumValues);
252 target.add(dropdownConf);
253 }
254 });
255
256 ActionsPanel<Serializable> actions = new ActionsPanel<>("actions", null);
257 item.add(actions);
258 actions.add(new ActionLink<>() {
259
260 private static final long serialVersionUID = -3722207913631435501L;
261
262 @Override
263 public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
264 model.getObject().remove(item.getIndex());
265
266 item.getParent().removeAll();
267 target.add(propertyDefContainer);
268 }
269 }, ActionLink.ActionType.DELETE, StringUtils.EMPTY, true).hideLabel();
270 if (model.getObject().size() > 1) {
271 if (item.getIndex() > 0) {
272 actions.add(new ActionLink<>() {
273
274 private static final long serialVersionUID = 2041211756396714619L;
275
276 @Override
277 public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
278 FormPropertyDefTO pre = model.getObject().get(item.getIndex() - 1);
279 model.getObject().set(item.getIndex(), pre);
280 model.getObject().set(item.getIndex() - 1, fpd);
281
282 item.getParent().removeAll();
283 target.add(propertyDefContainer);
284 }
285 }, ActionLink.ActionType.UP, StringUtils.EMPTY).hideLabel();
286 }
287 if (item.getIndex() < model.getObject().size() - 1) {
288 actions.add(new ActionLink<>() {
289
290 private static final long serialVersionUID = 2041211756396714619L;
291
292 @Override
293 public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
294 FormPropertyDefTO post = model.getObject().get(item.getIndex() + 1);
295 model.getObject().set(item.getIndex(), post);
296 model.getObject().set(item.getIndex() + 1, fpd);
297
298 item.getParent().removeAll();
299 target.add(propertyDefContainer);
300 }
301 }, ActionLink.ActionType.DOWN, StringUtils.EMPTY).hideLabel();
302 }
303 }
304 }
305 };
306 propertyDefContainer.add(propertyDefs.setReuseItems(true));
307
308 IndicatingAjaxButton addPropertyDef = new IndicatingAjaxButton("addPropertyDef") {
309
310 private static final long serialVersionUID = -4804368561204623354L;
311
312 @Override
313 protected void onSubmit(final AjaxRequestTarget target) {
314 model.getObject().add(new FormPropertyDefTO());
315 target.add(propertyDefContainer);
316 }
317 };
318 addPropertyDef.setDefaultFormProcessing(false);
319 propertyDefContainer.add(addPropertyDef);
320 }
321
322 @Override
323 public void onSubmit(final AjaxRequestTarget target) {
324 task.getFormPropertyDefs().clear();
325 task.getFormPropertyDefs().addAll(model.getObject());
326 try {
327 taskRestClient.update(TaskType.MACRO, task);
328
329 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
330 modal.close(target);
331 } catch (Exception e) {
332 LOG.error("While updating Macro Task {}", task.getKey(), e);
333 SyncopeConsoleSession.get().onException(e);
334 }
335 ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
336 }
337 }