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.panels;
20
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.Objects;
26 import java.util.stream.Collectors;
27 import org.apache.commons.lang3.LocaleUtils;
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.commons.lang3.tuple.MutablePair;
30 import org.apache.syncope.client.console.SyncopeConsoleSession;
31 import org.apache.syncope.client.console.SyncopeWebApplication;
32 import org.apache.syncope.client.console.rest.SchemaRestClient;
33 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
34 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
35 import org.apache.syncope.client.console.wizards.BaseAjaxWizardBuilder;
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.to.DerSchemaTO;
39 import org.apache.syncope.common.lib.to.PlainSchemaTO;
40 import org.apache.syncope.common.lib.to.SchemaTO;
41 import org.apache.syncope.common.lib.to.VirSchemaTO;
42 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
43 import org.apache.syncope.common.lib.types.SchemaType;
44 import org.apache.wicket.PageReference;
45 import org.apache.wicket.ajax.AjaxRequestTarget;
46 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
47 import org.apache.wicket.extensions.wizard.WizardModel;
48 import org.apache.wicket.extensions.wizard.WizardStep;
49 import org.apache.wicket.markup.html.list.ListItem;
50 import org.apache.wicket.markup.html.list.ListView;
51 import org.apache.wicket.markup.html.panel.Panel;
52 import org.apache.wicket.model.IModel;
53 import org.apache.wicket.model.Model;
54 import org.apache.wicket.model.ResourceModel;
55 import org.apache.wicket.model.util.ListModel;
56 import org.apache.wicket.request.cycle.RequestCycle;
57 import org.apache.wicket.validation.ValidationError;
58
59 public class SchemaTypeWizardBuilder extends BaseAjaxWizardBuilder<SchemaTO> {
60
61 private static final long serialVersionUID = -3893521796674873644L;
62
63 protected final SchemaType schemaType;
64
65 protected final SchemaRestClient schemaRestClient;
66
67 protected final ListModel<MutablePair<Locale, String>> translations = new ListModel<>(new ArrayList<>());
68
69 public SchemaTypeWizardBuilder(
70 final SchemaTO schemaTO,
71 final SchemaRestClient schemaRestClient,
72 final PageReference pageRef) {
73
74 super(schemaTO, pageRef);
75
76 this.schemaType = SchemaType.fromToClass(schemaTO.getClass());
77 this.schemaRestClient = schemaRestClient;
78 }
79
80 @Override
81 protected Serializable onApplyInternal(final SchemaTO modelObject) {
82 modelObject.getLabels().clear();
83 modelObject.getLabels().putAll(translations.getObject().stream().
84 filter(Objects::nonNull).
85 filter(translation -> translation.getKey() != null).
86 filter(translation -> translation.getValue() != null).
87 collect(Collectors.toMap(MutablePair::getKey, MutablePair::getValue)));
88
89 if (getOriginalItem() == null || StringUtils.isBlank(getOriginalItem().getKey())) {
90 schemaRestClient.create(schemaType, modelObject);
91 } else {
92 schemaRestClient.update(schemaType, modelObject);
93 }
94
95 return null;
96 }
97
98 @Override
99 protected WizardModel buildModelSteps(final SchemaTO modelObject, final WizardModel wizardModel) {
100 wizardModel.add(new Details(modelObject));
101 wizardModel.add(new Labels(modelObject));
102 return wizardModel;
103 }
104
105 public class Details extends WizardStep {
106
107 private static final long serialVersionUID = 382498949020534783L;
108
109 public Details(final SchemaTO modelObject) {
110 AjaxDropDownChoicePanel<SchemaType> kind =
111 new AjaxDropDownChoicePanel<>("kind", getString("kind"), new Model<>());
112 kind.setChoices(List.of(SchemaType.values()));
113 kind.setOutputMarkupId(true);
114 kind.setModelObject(schemaType);
115 kind.setEnabled(false);
116 add(kind);
117
118 Panel detailsPanel;
119 switch (schemaType) {
120 case DERIVED:
121 detailsPanel = new DerSchemaDetails("details", (DerSchemaTO) modelObject);
122 break;
123
124 case VIRTUAL:
125 detailsPanel = SyncopeWebApplication.get().getVirSchemaDetailsPanelProvider().
126 get("details", (VirSchemaTO) modelObject);
127 break;
128
129 case PLAIN:
130 default:
131 detailsPanel = new PlainSchemaDetails("details", (PlainSchemaTO) modelObject);
132 }
133 add(detailsPanel.setOutputMarkupId(true));
134 }
135 }
136
137 public class Labels extends WizardStep {
138
139 private static final long serialVersionUID = -3130973642912822270L;
140
141 public Labels(final SchemaTO modelObject) {
142 setTitleModel(new ResourceModel("translations"));
143 setOutputMarkupId(true);
144
145 translations.getObject().clear();
146 modelObject.getLabels().forEach(
147 (locale, display) -> translations.getObject().add(MutablePair.of(locale, display)));
148
149 ListView<MutablePair<Locale, String>> labels = new ListView<>("labels", translations) {
150
151 private static final long serialVersionUID = -8746795666847966508L;
152
153 @Override
154 protected void populateItem(final ListItem<MutablePair<Locale, String>> item) {
155 MutablePair<Locale, String> entry = item.getModelObject();
156
157 AjaxTextFieldPanel locale = new AjaxTextFieldPanel("locale", "locale", new Model<>(), true);
158 locale.getField().setModel(new IModel<>() {
159
160 private static final long serialVersionUID = 1500045101360533133L;
161
162 @Override
163 public String getObject() {
164 return entry.getLeft() == null ? null : entry.getLeft().toString();
165 }
166
167 @Override
168 public void setObject(final String object) {
169 entry.setLeft(LocaleUtils.toLocale(object));
170 }
171 });
172 locale.setRequired(true).hideLabel();
173 locale.setChoices(SyncopeConsoleSession.get().getSupportedLocales().stream().
174 map(Objects::toString).collect(Collectors.toList()));
175 locale.addValidator(validatable -> {
176 try {
177 LocaleUtils.toLocale(validatable.getValue());
178 } catch (Exception e) {
179 LOG.error("Invalid Locale: {}", validatable.getValue(), e);
180 validatable.error(new ValidationError("Invalid Locale: " + validatable.getValue()));
181
182 RequestCycle.get().find(AjaxRequestTarget.class).
183 ifPresent(target -> target.add(Labels.this));
184 }
185 });
186 item.add(locale);
187
188 AjaxTextFieldPanel display = new AjaxTextFieldPanel("display", "display", new Model<>());
189 display.getField().setModel(new IModel<>() {
190
191 private static final long serialVersionUID = 1500045101360533133L;
192
193 @Override
194 public String getObject() {
195 return entry.getRight();
196 }
197
198 @Override
199 public void setObject(final String object) {
200 entry.setRight(object);
201 }
202 });
203 display.setRequired(true).hideLabel();
204 item.add(display);
205
206 ActionsPanel<Serializable> actions = new ActionsPanel<>("toRemove", null);
207 actions.add(new ActionLink<>() {
208
209 private static final long serialVersionUID = -3722207913631435501L;
210
211 @Override
212 public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
213 translations.getObject().remove(item.getIndex());
214
215 item.getParent().removeAll();
216 target.add(Labels.this);
217 }
218 }, ActionLink.ActionType.DELETE, IdRepoEntitlement.SCHEMA_UPDATE, true).hideLabel();
219 item.add(actions);
220 }
221 };
222 add(labels.setReuseItems(true));
223
224 IndicatingAjaxButton addLabel = new IndicatingAjaxButton("addLabel") {
225
226 private static final long serialVersionUID = -4804368561204623354L;
227
228 @Override
229 protected void onSubmit(final AjaxRequestTarget target) {
230 translations.getObject().add(MutablePair.of(null, null));
231 target.add(Labels.this);
232 }
233 };
234 add(addLabel.setDefaultFormProcessing(false));
235 }
236 }
237 }