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.wizards.any;
20
21 import java.io.Serializable;
22 import java.util.List;
23 import java.util.Optional;
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.Future;
26 import org.apache.commons.lang3.tuple.Pair;
27 import org.apache.syncope.client.console.SyncopeConsoleSession;
28 import org.apache.syncope.client.console.SyncopeWebApplication;
29 import org.apache.syncope.client.console.layout.AnyObjectFormLayoutInfo;
30 import org.apache.syncope.client.console.layout.GroupFormLayoutInfo;
31 import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
32 import org.apache.syncope.client.ui.commons.layout.AbstractAnyFormLayout;
33 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
34 import org.apache.syncope.client.ui.commons.wizards.any.AbstractAnyWizardBuilder;
35 import org.apache.syncope.client.ui.commons.wizards.any.AnyForm;
36 import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
37 import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper;
38 import org.apache.syncope.common.lib.Attr;
39 import org.apache.syncope.common.lib.to.AnyObjectTO;
40 import org.apache.syncope.common.lib.to.AnyTO;
41 import org.apache.syncope.common.lib.to.GroupTO;
42 import org.apache.syncope.common.lib.to.GroupableRelatableTO;
43 import org.apache.syncope.common.lib.to.UserTO;
44 import org.apache.wicket.PageReference;
45 import org.apache.wicket.extensions.wizard.WizardModel;
46
47 public abstract class AnyWizardBuilder<A extends AnyTO> extends AbstractAnyWizardBuilder<A> {
48
49 private static final long serialVersionUID = -2480279868319546243L;
50
51 @SuppressWarnings("unchecked")
52 protected static <T extends AnyTO> AnyWrapper<T> wrapper(final T anyTO) {
53 return (AnyWrapper<T>) (anyTO instanceof UserTO
54 ? new UserWrapper((UserTO) anyTO)
55 : anyTO instanceof GroupTO
56 ? new GroupWrapper((GroupTO) anyTO)
57 : new AnyObjectWrapper((AnyObjectTO) anyTO));
58 }
59
60 protected final List<String> anyTypeClasses;
61
62 protected AbstractAnyFormLayout<A, ? extends AnyForm<A>> formLayoutInfo;
63
64
65
66
67
68
69
70
71
72 public AnyWizardBuilder(
73 final A anyTO,
74 final List<String> anyTypeClasses,
75 final AbstractAnyFormLayout<A, ? extends AnyForm<A>> formLayoutInfo,
76 final PageReference pageRef) {
77
78 super(wrapper(anyTO), pageRef);
79 this.anyTypeClasses = anyTypeClasses;
80 this.formLayoutInfo = formLayoutInfo;
81 }
82
83
84
85
86
87
88
89
90
91 public AnyWizardBuilder(
92 final AnyWrapper<A> wrapper,
93 final List<String> anyTypeClasses,
94 final AbstractAnyFormLayout<A, ? extends AnyForm<A>> formLayoutInfo,
95 final PageReference pageRef) {
96
97 super(wrapper, pageRef);
98 this.anyTypeClasses = anyTypeClasses;
99 this.formLayoutInfo = formLayoutInfo;
100 }
101
102 @Override
103 protected WizardModel buildModelSteps(final AnyWrapper<A> modelObject, final WizardModel wizardModel) {
104
105 addOptionalDetailsPanel(modelObject).ifPresent(wizardModel::add);
106
107 if ((this instanceof GroupWizardBuilder)
108 && (modelObject.getInnerObject() instanceof GroupTO)
109 && (formLayoutInfo instanceof GroupFormLayoutInfo)) {
110
111 GroupFormLayoutInfo groupFormLayoutInfo = GroupFormLayoutInfo.class.cast(formLayoutInfo);
112 if (groupFormLayoutInfo.isOwnership()) {
113 wizardModel.add(new Ownership(GroupWrapper.class.cast(modelObject), pageRef));
114 }
115 if (groupFormLayoutInfo.isDynamicMemberships()) {
116 wizardModel.add(new DynamicMemberships(GroupWrapper.class.cast(modelObject), pageRef));
117 }
118 }
119
120 if (formLayoutInfo.isAuxClasses()) {
121 wizardModel.add(new ConsoleAuxClasses(modelObject, anyTypeClasses));
122 }
123
124 if (formLayoutInfo.isGroups()) {
125 wizardModel.add(new Groups(modelObject, mode == AjaxWizard.Mode.TEMPLATE));
126 }
127
128
129 if (formLayoutInfo.isPlainAttrs()) {
130 wizardModel.add(
131 new PlainAttrs(modelObject, mode, anyTypeClasses, formLayoutInfo.getWhichPlainAttrs()) {
132
133 private static final long serialVersionUID = 8167894751609598306L;
134
135 @Override
136 public PageReference getPageReference() {
137 return pageRef;
138 }
139 });
140 }
141 if (formLayoutInfo.isDerAttrs() && mode != AjaxWizard.Mode.TEMPLATE) {
142 wizardModel.add(new DerAttrs(modelObject, anyTypeClasses, formLayoutInfo.getWhichDerAttrs()));
143 }
144 if (formLayoutInfo.isVirAttrs()) {
145 wizardModel.add(new VirAttrs(modelObject, mode, anyTypeClasses, formLayoutInfo.getWhichVirAttrs()));
146 }
147
148
149 if ((this instanceof UserWizardBuilder)
150 && modelObject instanceof UserWrapper
151 && formLayoutInfo instanceof UserFormLayoutInfo
152 && UserFormLayoutInfo.class.cast(formLayoutInfo).isRoles()) {
153
154 wizardModel.add(new Roles((UserWrapper) modelObject));
155 }
156
157
158 if ((formLayoutInfo instanceof UserFormLayoutInfo
159 && UserFormLayoutInfo.class.cast(formLayoutInfo).isRelationships())
160 || (formLayoutInfo instanceof AnyObjectFormLayoutInfo
161 && AnyObjectFormLayoutInfo.class.cast(formLayoutInfo).isRelationships())) {
162
163 wizardModel.add(new Relationships(modelObject, pageRef));
164 }
165
166 SyncopeWebApplication.get().getAnyWizardBuilderAdditionalSteps().
167 buildModelSteps(modelObject, wizardModel, formLayoutInfo);
168
169 return wizardModel;
170 }
171
172 protected Optional<Details<A>> addOptionalDetailsPanel(final AnyWrapper<A> modelObject) {
173 if (modelObject.getInnerObject().getKey() == null) {
174 return Optional.empty();
175 } else {
176 return Optional.of(new Details<>(modelObject, mode == AjaxWizard.Mode.TEMPLATE, true, pageRef));
177 }
178 }
179
180 @Override
181 protected void fixPlainAndVirAttrs(final AnyTO updated, final AnyTO original) {
182
183
184 for (Attr plainAttr : original.getPlainAttrs()) {
185 if (updated.getPlainAttr(plainAttr.getSchema()).isEmpty()) {
186 updated.getPlainAttrs().add(plainAttr);
187 }
188 }
189 for (Attr virAttr : original.getVirAttrs()) {
190 if (updated.getVirAttr(virAttr.getSchema()).isEmpty()) {
191 updated.getVirAttrs().add(virAttr);
192 }
193 }
194
195 if (updated instanceof GroupableRelatableTO && original instanceof GroupableRelatableTO) {
196 GroupableRelatableTO.class.cast(original).getMemberships().
197 forEach(oMemb -> GroupableRelatableTO.class.cast(updated).getMembership(oMemb.getGroupKey()).
198 ifPresent(uMemb -> {
199 oMemb.getPlainAttrs().stream().
200 filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isEmpty()).
201 forEach(attr -> uMemb.getPlainAttrs().add(attr));
202 oMemb.getVirAttrs().stream().
203 filter(attr -> uMemb.getVirAttr(attr.getSchema()).isEmpty()).
204 forEach(attr -> uMemb.getVirAttrs().add(attr));
205 }));
206 }
207
208
209
210 updated.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty());
211 updated.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty());
212 if (updated instanceof GroupableRelatableTO) {
213 GroupableRelatableTO.class.cast(updated).getMemberships().forEach(memb -> {
214 memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty());
215 memb.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty());
216 });
217 }
218 }
219
220 @Override
221 protected long getMaxWaitTimeInSeconds() {
222 return SyncopeWebApplication.get().getMaxWaitTimeInSeconds();
223 }
224
225 @Override
226 protected void sendError(final Exception exception) {
227 SyncopeConsoleSession.get().onException(exception);
228 }
229
230 @Override
231 protected void sendWarning(final String message) {
232 SyncopeConsoleSession.get().warn(message);
233 }
234
235 @Override
236 protected Future<Pair<Serializable, Serializable>> execute(
237 final Callable<Pair<Serializable, Serializable>> future) {
238
239 return SyncopeConsoleSession.get().execute(future);
240 }
241 }