View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.console.pages;
20  
21  import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
22  import java.io.Serializable;
23  import java.util.List;
24  import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
25  import org.apache.syncope.client.console.SyncopeConsoleSession;
26  import org.apache.syncope.client.console.panels.Realm;
27  import org.apache.syncope.client.console.panels.RealmChoicePanel;
28  import org.apache.syncope.client.console.panels.RealmChoicePanel.ChosenRealm;
29  import org.apache.syncope.client.console.rest.AnyTypeRestClient;
30  import org.apache.syncope.client.console.rest.RealmRestClient;
31  import org.apache.syncope.client.console.tasks.TemplatesTogglePanel;
32  import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
33  import org.apache.syncope.client.console.wizards.any.ResultPanel;
34  import org.apache.syncope.client.ui.commons.Constants;
35  import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
36  import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
37  import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
38  import org.apache.syncope.common.lib.to.AnyTO;
39  import org.apache.syncope.common.lib.to.AnyTypeTO;
40  import org.apache.syncope.common.lib.to.ProvisioningResult;
41  import org.apache.syncope.common.lib.to.RealmTO;
42  import org.apache.syncope.common.lib.to.TemplatableTO;
43  import org.apache.wicket.PageReference;
44  import org.apache.wicket.ajax.AjaxRequestTarget;
45  import org.apache.wicket.event.Broadcast;
46  import org.apache.wicket.event.IEvent;
47  import org.apache.wicket.markup.html.WebMarkupContainer;
48  import org.apache.wicket.markup.html.basic.Label;
49  import org.apache.wicket.model.CompoundPropertyModel;
50  import org.apache.wicket.model.IModel;
51  import org.apache.wicket.model.Model;
52  import org.apache.wicket.request.mapper.parameter.PageParameters;
53  import org.apache.wicket.spring.injection.annot.SpringBean;
54  
55  public class Realms extends BasePage {
56  
57      private static final long serialVersionUID = -1100228004207271270L;
58  
59      public static final String SELECTED_INDEX = "selectedIndex";
60  
61      public static final String INITIAL_REALM = "initialRealm";
62  
63      @SpringBean
64      protected RealmRestClient realmRestClient;
65  
66      @SpringBean
67      protected AnyTypeRestClient anyTypeRestClient;
68  
69      protected final TemplatesTogglePanel templates;
70  
71      protected final RealmChoicePanel realmChoicePanel;
72  
73      protected final WebMarkupContainer content;
74  
75      protected final BaseModal<RealmTO> modal;
76  
77      protected final BaseModal<Serializable> templateModal;
78  
79      public Realms(final PageParameters parameters) {
80          super(parameters);
81  
82          templates = new TemplatesTogglePanel(BaseModal.CONTENT_ID, this, getPageReference()) {
83  
84              private static final long serialVersionUID = 4828350561653999922L;
85  
86              @Override
87              protected Serializable onApplyInternal(
88                      final TemplatableTO targetObject, final String type, final AnyTO anyTO) {
89  
90                  targetObject.getTemplates().put(type, anyTO);
91                  realmRestClient.update(RealmTO.class.cast(targetObject));
92                  return targetObject;
93              }
94          };
95  
96          body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
97  
98          content = new WebMarkupContainer("content");
99  
100         realmChoicePanel = buildRealmChoicePanel(parameters.get(INITIAL_REALM).toOptionalString(), getPageReference());
101         content.add(realmChoicePanel);
102 
103         content.add(new Label("body", "Root realm"));
104         content.setOutputMarkupId(true);
105         body.add(content);
106 
107         modal = new BaseModal<>("modal");
108         modal.size(Modal.Size.Large);
109         content.add(modal);
110 
111         content.add(templates);
112 
113         templateModal = new BaseModal<>("templateModal") {
114 
115             private static final long serialVersionUID = 5787433530654262016L;
116 
117             @Override
118             protected void onConfigure() {
119                 super.onConfigure();
120                 setFooterVisible(false);
121             }
122         };
123         templateModal.size(Modal.Size.Large);
124         content.add(templateModal);
125 
126         modal.setWindowClosedCallback(target -> {
127             target.add(realmChoicePanel.reloadRealmTree(target));
128             target.add(content);
129             modal.show(false);
130         });
131 
132         templateModal.setWindowClosedCallback(target -> {
133             target.add(content);
134             templateModal.show(false);
135         });
136 
137         updateRealmContent(realmChoicePanel.getCurrentRealm(), parameters.get(SELECTED_INDEX).toInt(0));
138     }
139 
140     protected RealmChoicePanel buildRealmChoicePanel(final String initialRealm, final PageReference pageRef) {
141         RealmChoicePanel panel = new RealmChoicePanel("realmChoicePanel", initialRealm, realmRestClient, pageRef);
142         panel.setOutputMarkupId(true);
143         return panel;
144     }
145 
146     public RealmChoicePanel getRealmChoicePanel() {
147         return realmChoicePanel;
148     }
149 
150     @Override
151     public void onEvent(final IEvent<?> event) {
152         super.onEvent(event);
153 
154         if (event.getPayload() instanceof ChosenRealm) {
155             @SuppressWarnings("unchecked")
156             ChosenRealm<RealmTO> choosenRealm = ChosenRealm.class.cast(event.getPayload());
157             updateRealmContent(choosenRealm.getObj(), 0);
158             choosenRealm.getTarget().add(content);
159         } else if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
160             AjaxWizard.NewItemEvent<?> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
161             WizardModalPanel<?> modalPanel = newItemEvent.getModalPanel();
162 
163             if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
164                 final IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
165                 templateModal.setFormModel(model);
166                 templateModal.header(newItemEvent.getTitleModel());
167                 newItemEvent.getTarget().ifPresent(t -> t.add(templateModal.setContent(modalPanel)));
168                 templateModal.show(true);
169             } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
170                 newItemEvent.getTarget().ifPresent(templateModal::close);
171             } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
172                 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
173                 newItemEvent.getTarget().ifPresent(t -> {
174                     ((BasePage) getPage()).getNotificationPanel().refresh(t);
175                     templateModal.close(t);
176                 });
177             }
178         }
179     }
180 
181     protected WebMarkupContainer updateRealmContent(final RealmTO realmTO, final int selectedIndex) {
182         if (realmTO != null) {
183             content.addOrReplace(new Content(realmTO, anyTypeRestClient.listAnyTypes(), selectedIndex));
184         }
185         return content;
186     }
187 
188     protected class Content extends Realm {
189 
190         private static final long serialVersionUID = 8221398624379357183L;
191 
192         protected Content(final RealmTO realmTO, final List<AnyTypeTO> anyTypes, final int selectedIndex) {
193             super("body", realmTO, anyTypes, selectedIndex, Realms.this.getPageReference());
194         }
195 
196         @Override
197         protected void onClickTemplate(final AjaxRequestTarget target) {
198             templates.setTargetObject(realmTO);
199             templates.toggle(target, true);
200         }
201 
202         @Override
203         protected void setWindowClosedReloadCallback(final BaseModal<?> modal) {
204             modal.setWindowClosedCallback(target -> {
205                 if (modal.getContent() instanceof ResultPanel) {
206                     Object result = ResultPanel.class.cast(modal.getContent()).getResult();
207 
208                     RealmTO newRealmTO = RealmTO.class.cast(ProvisioningResult.class.cast(result).getEntity());
209                     // reload realmChoicePanel label too - SYNCOPE-1151
210                     target.add(realmChoicePanel.reloadRealmTree(target, Model.of(newRealmTO)));
211                     realmChoicePanel.setCurrentRealm(newRealmTO);
212                     send(Realms.this, Broadcast.DEPTH, new ChosenRealm<>(newRealmTO, target));
213                 } else {
214                     target.add(realmChoicePanel.reloadRealmTree(target));
215                 }
216                 target.add(content);
217                 modal.show(false);
218             });
219         }
220 
221         @Override
222         protected void onClickCreate(final AjaxRequestTarget target) {
223             this.wizardBuilder.setParentPath(realmChoicePanel.getCurrentRealm().getFullPath());
224             send(this, Broadcast.EXACT, new AjaxWizard.NewItemActionEvent<RealmTO>(new RealmTO(), target) {
225 
226                 @Override
227                 public String getEventDescription() {
228                     return "realm.new";
229                 }
230             });
231         }
232 
233         @Override
234         protected void onClickEdit(final AjaxRequestTarget target, final RealmTO realmTO) {
235             this.wizardBuilder.setParentPath(realmTO.getFullPath());
236             send(this, Broadcast.EXACT, new AjaxWizard.EditItemActionEvent<RealmTO>(realmTO, target) {
237 
238                 @Override
239                 public String getEventDescription() {
240                     return "realm.edit";
241                 }
242             });
243         }
244 
245         @Override
246         protected void onClickDelete(final AjaxRequestTarget target, final RealmTO realmTO) {
247             try {
248                 if (realmTO.getKey() == null) {
249                     throw new Exception("Root realm cannot be deleted");
250                 }
251                 realmRestClient.delete(realmTO.getFullPath());
252                 RealmTO parent = realmChoicePanel.moveToParentRealm(realmTO.getKey());
253                 target.add(realmChoicePanel.reloadRealmTree(target));
254 
255                 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
256                 updateRealmContent(parent, selectedIndex);
257                 target.add(content);
258             } catch (Exception e) {
259                 LOG.error("While deleting realm", e);
260                 // Escape line breaks
261                 SyncopeConsoleSession.get().error(e.getMessage().replace("\n", " "));
262             }
263             ((BaseWebPage) Realms.this.getPage()).getNotificationPanel().refresh(target);
264         }
265     }
266 }