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.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.commons.lang3.tuple.Pair;
28 import org.apache.commons.lang3.tuple.Triple;
29 import org.apache.syncope.client.console.SyncopeWebApplication;
30 import org.apache.syncope.client.console.panels.ListViewPanel;
31 import org.apache.syncope.client.console.panels.MultilevelPanel;
32 import org.apache.syncope.client.console.panels.PropagationErrorPanel;
33 import org.apache.syncope.client.console.panels.RemoteObjectPanel;
34 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
35 import org.apache.syncope.client.ui.commons.Constants;
36 import org.apache.syncope.client.ui.commons.status.ConnObjectWrapper;
37 import org.apache.syncope.client.ui.commons.status.Status;
38 import org.apache.syncope.client.ui.commons.status.StatusBean;
39 import org.apache.syncope.client.ui.commons.status.StatusUtils;
40 import org.apache.syncope.common.lib.to.AnyTO;
41 import org.apache.syncope.common.lib.to.ConnObject;
42 import org.apache.syncope.common.lib.to.GroupTO;
43 import org.apache.syncope.common.lib.to.UserTO;
44 import org.apache.wicket.Component;
45 import org.apache.wicket.PageReference;
46 import org.apache.wicket.ajax.AjaxRequestTarget;
47 import org.apache.wicket.markup.html.panel.Panel;
48 import org.apache.wicket.model.IModel;
49 import org.apache.wicket.model.ResourceModel;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 public class StatusPanel extends Panel {
54
55 private static final long serialVersionUID = -4013796607157549641L;
56
57 protected static final Logger LOG = LoggerFactory.getLogger(StatusPanel.class);
58
59 protected Map<String, StatusBean> initialStatusBeanMap;
60
61 protected ListViewPanel<?> listViewPanel;
62
63 public <T extends AnyTO> StatusPanel(
64 final String id,
65 final T any,
66 final IModel<List<StatusBean>> model,
67 final PageReference pageRef) {
68
69 super(id);
70 init(any, model,
71 SyncopeWebApplication.get().getStatusProvider().get(any, any.getResources()), pageRef, false);
72 }
73
74 public <T extends AnyTO> StatusPanel(
75 final String id,
76 final T any,
77 final IModel<List<StatusBean>> model,
78 final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects,
79 final PageReference pageRef) {
80
81 super(id);
82 init(any, model, connObjects, pageRef, true);
83 }
84
85 protected void init(
86 final AnyTO any,
87 final IModel<List<StatusBean>> model,
88 final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects,
89 final PageReference pageRef,
90 final boolean enableConnObjectLink) {
91
92 final List<StatusBean> statusBeans = new ArrayList<>(connObjects.size() + 1);
93 initialStatusBeanMap = new LinkedHashMap<>(connObjects.size() + 1);
94
95 final StatusBean syncope = new StatusBean(any, Constants.SYNCOPE);
96
97 if (any instanceof UserTO) {
98 syncope.setConnObjectLink(((UserTO) any).getUsername());
99
100 Status syncopeStatus = Status.UNDEFINED;
101 if (((UserTO) any).getStatus() != null) {
102 try {
103 syncopeStatus = Status.valueOf(((UserTO) any).getStatus().toUpperCase());
104 } catch (IllegalArgumentException e) {
105 LOG.warn("Unexpected status found: {}", ((UserTO) any).getStatus(), e);
106 }
107 }
108 syncope.setStatus(syncopeStatus);
109 } else if (any instanceof GroupTO) {
110 syncope.setConnObjectLink(((GroupTO) any).getName());
111 syncope.setStatus(Status.ACTIVE);
112 }
113
114 statusBeans.add(syncope);
115 initialStatusBeanMap.put(syncope.getResource(), syncope);
116
117 Map<String, String> failureReasons = new HashMap<>();
118 connObjects.forEach(triple -> {
119 ConnObjectWrapper connObjectWrapper = triple.getMiddle();
120 StatusBean statusBean = StatusUtils.getStatusBean(connObjectWrapper.getAny(),
121 connObjectWrapper.getResource(),
122 connObjectWrapper.getConnObjectTO(),
123 any instanceof GroupTO);
124
125 initialStatusBeanMap.put(connObjectWrapper.getResource(), statusBean);
126 statusBeans.add(statusBean);
127
128 if (StringUtils.isNotBlank(triple.getRight())) {
129 failureReasons.put(connObjectWrapper.getResource(), triple.getRight());
130 }
131 });
132
133 MultilevelPanel mlp = new MultilevelPanel("resources");
134 add(mlp);
135
136 ListViewPanel.Builder<StatusBean> builder = new ListViewPanel.Builder<>(StatusBean.class, pageRef) {
137
138 private static final long serialVersionUID = -6809736686861678498L;
139
140 @Override
141 protected Component getValueComponent(final String key, final StatusBean bean) {
142 if ("status".equalsIgnoreCase(key)) {
143 return StatusUtils.getStatusImagePanel("field", bean.getStatus());
144 } else {
145 return super.getValueComponent(key, bean);
146 }
147 }
148 };
149 builder.setModel(model);
150 builder.setItems(statusBeans);
151 builder.includes("resource", "connObjectLink", "status");
152 builder.withChecks(ListViewPanel.CheckAvailability.NONE);
153 builder.setReuseItem(false);
154
155 ActionLink<StatusBean> connObjectLink = new ActionLink<>() {
156
157 private static final long serialVersionUID = -3722207913631435501L;
158
159 @Override
160 protected boolean statusCondition(final StatusBean bean) {
161 Pair<ConnObject, ConnObject> pair =
162 getConnObjectTOs(bean.getKey(), bean.getResource(), connObjects);
163 return pair != null && pair.getRight() != null;
164 }
165
166 @Override
167 public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
168 mlp.next(bean.getResource(), new RemoteAnyPanel(bean, connObjects), target);
169 }
170 };
171 if (!enableConnObjectLink) {
172 connObjectLink.disable();
173 }
174 SyncopeWebApplication.get().getStatusProvider().addConnObjectLink(builder, connObjectLink);
175
176 builder.addAction(new ActionLink<>() {
177
178 private static final long serialVersionUID = -3722207913631435501L;
179
180 @Override
181 protected boolean statusCondition(final StatusBean bean) {
182 return failureReasons.containsKey(bean.getResource());
183 }
184
185 @Override
186 public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
187 mlp.next(bean.getResource(), new PropagationErrorPanel(failureReasons.get(bean.getResource())), target);
188 }
189 }, ActionLink.ActionType.PROPAGATION_TASKS, StringUtils.EMPTY);
190
191 listViewPanel = ListViewPanel.class.cast(builder.build(MultilevelPanel.FIRST_LEVEL_ID));
192 mlp.setFirstLevel(listViewPanel);
193 }
194
195 public void setCheckAvailability(final ListViewPanel.CheckAvailability check) {
196 listViewPanel.setCheckAvailability(check);
197 }
198
199 public Map<String, StatusBean> getInitialStatusBeanMap() {
200 return initialStatusBeanMap;
201 }
202
203 protected static Pair<ConnObject, ConnObject> getConnObjectTOs(
204 final String anyKey,
205 final String resource,
206 final List<Triple<ConnObject, ConnObjectWrapper, String>> objects) {
207
208 for (Triple<ConnObject, ConnObjectWrapper, String> object : objects) {
209 if (anyKey.equals(object.getMiddle().getAny().getKey())
210 && resource.equalsIgnoreCase(object.getMiddle().getResource())) {
211
212 return Pair.of(object.getLeft(), object.getMiddle().getConnObjectTO());
213 }
214 }
215
216 return null;
217 }
218
219 static class RemoteAnyPanel extends RemoteObjectPanel {
220
221 private static final long serialVersionUID = 4303365227411467563L;
222
223 protected final StatusBean bean;
224
225 protected final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects;
226
227 RemoteAnyPanel(final StatusBean bean, final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects) {
228 this.bean = bean;
229 this.connObjects = connObjects;
230
231 add(new ConnObjectPanel(
232 REMOTE_OBJECT_PANEL_ID,
233 Pair.<IModel<?>, IModel<?>>of(new ResourceModel("before"), new ResourceModel("after")),
234 getConnObjectTOs(),
235 false));
236 }
237
238 @Override
239 protected final Pair<ConnObject, ConnObject> getConnObjectTOs() {
240 return StatusPanel.getConnObjectTOs(bean.getKey(), bean.getResource(), connObjects);
241 }
242 }
243 }