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.wizards;
20  
21  import java.io.Serializable;
22  import java.util.List;
23  import java.util.stream.Collectors;
24  import org.apache.commons.lang3.StringUtils;
25  import org.apache.syncope.client.console.SyncopeWebApplication;
26  import org.apache.syncope.client.console.panels.BeanPanel;
27  import org.apache.syncope.client.console.rest.AttrRepoRestClient;
28  import org.apache.syncope.client.console.wizards.mapping.AttrRepoMappingPanel;
29  import org.apache.syncope.client.ui.commons.Constants;
30  import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
31  import org.apache.syncope.client.ui.commons.markup.html.form.AjaxSpinnerFieldPanel;
32  import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
33  import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
34  import org.apache.syncope.common.lib.attr.AttrRepoConf;
35  import org.apache.syncope.common.lib.to.AttrRepoTO;
36  import org.apache.syncope.common.lib.types.AttrRepoState;
37  import org.apache.wicket.PageReference;
38  import org.apache.wicket.ajax.AjaxEventBehavior;
39  import org.apache.wicket.ajax.AjaxRequestTarget;
40  import org.apache.wicket.extensions.wizard.WizardModel;
41  import org.apache.wicket.extensions.wizard.WizardStep;
42  import org.apache.wicket.model.LoadableDetachableModel;
43  import org.apache.wicket.model.Model;
44  import org.apache.wicket.model.PropertyModel;
45  import org.springframework.util.ClassUtils;
46  
47  public class AttrRepoWizardBuilder extends BaseAjaxWizardBuilder<AttrRepoTO> {
48  
49      private static final long serialVersionUID = -6163230263062920394L;
50  
51      protected final LoadableDetachableModel<List<String>> attrRepoConfs;
52  
53      protected final AttrRepoRestClient attrRepoRestClient;
54  
55      protected final Model<Class<? extends AttrRepoConf>> attrRepoConfClass = Model.of();
56  
57      public AttrRepoWizardBuilder(
58              final AttrRepoTO defaultItem,
59              final AttrRepoRestClient attrRepoRestClient,
60              final PageReference pageRef) {
61  
62          super(defaultItem, pageRef);
63  
64          attrRepoConfs = new LoadableDetachableModel<>() {
65  
66              private static final long serialVersionUID = 5275935387613157437L;
67  
68              @Override
69              protected List<String> load() {
70                  return SyncopeWebApplication.get().getLookup().getClasses(AttrRepoConf.class).stream().
71                          map(Class::getName).sorted().collect(Collectors.toList());
72              }
73          };
74          this.attrRepoRestClient = attrRepoRestClient;
75      }
76  
77      @Override
78      protected Serializable onApplyInternal(final AttrRepoTO modelObject) {
79          if (mode == AjaxWizard.Mode.CREATE) {
80              attrRepoRestClient.create(modelObject);
81          } else {
82              attrRepoRestClient.update(modelObject);
83          }
84          return modelObject;
85      }
86  
87      @Override
88      protected WizardModel buildModelSteps(final AttrRepoTO modelObject, final WizardModel wizardModel) {
89          wizardModel.add(new Profile(modelObject, attrRepoConfs, attrRepoConfClass));
90          wizardModel.add(new Configuration(modelObject));
91          wizardModel.add(new Mapping(modelObject));
92          return wizardModel;
93      }
94  
95      protected static class Profile extends WizardStep {
96  
97          private static final long serialVersionUID = -3043839139187792810L;
98  
99          Profile(
100                 final AttrRepoTO attrRepo,
101                 final LoadableDetachableModel<List<String>> attrRepoConfs,
102                 final Model<Class<? extends AttrRepoConf>> attrRepoConfClass) {
103 
104             boolean isNew = attrRepo.getConf() == null;
105             if (!isNew) {
106                 attrRepoConfClass.setObject(attrRepo.getConf().getClass());
107             }
108 
109             AjaxTextFieldPanel key = new AjaxTextFieldPanel(
110                     Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME,
111                     new PropertyModel<>(attrRepo, Constants.KEY_FIELD_NAME));
112             key.addRequiredLabel();
113             key.setEnabled(isNew);
114             add(key);
115 
116             AjaxTextFieldPanel description = new AjaxTextFieldPanel(
117                     Constants.DESCRIPTION_FIELD_NAME, getString(Constants.DESCRIPTION_FIELD_NAME),
118                     new PropertyModel<>(attrRepo, Constants.DESCRIPTION_FIELD_NAME));
119             add(description);
120 
121             AjaxDropDownChoicePanel<AttrRepoState> state = new AjaxDropDownChoicePanel<>(
122                     "state", getString("state"), new PropertyModel<>(attrRepo, "state"));
123             state.setChoices(List.of(AttrRepoState.values()));
124             state.addRequiredLabel();
125             state.setNullValid(false);
126             add(state);
127 
128             add(new AjaxSpinnerFieldPanel.Builder<Integer>().build(
129                     "order",
130                     "order",
131                     Integer.class,
132                     new PropertyModel<>(attrRepo, "order")).addRequiredLabel());
133 
134             AjaxDropDownChoicePanel<String> conf = new AjaxDropDownChoicePanel<>("conf", getString("type"), isNew
135                     ? Model.of()
136                     : Model.of(attrRepo.getConf().getClass().getName()));
137             conf.setChoices(attrRepoConfs.getObject());
138             conf.addRequiredLabel();
139             conf.setNullValid(false);
140             conf.setEnabled(isNew);
141             conf.add(new AjaxEventBehavior(Constants.ON_CHANGE) {
142 
143                 private static final long serialVersionUID = -7133385027739964990L;
144 
145                 @SuppressWarnings("unchecked")
146                 @Override
147                 protected void onEvent(final AjaxRequestTarget target) {
148                     try {
149                         Class<? extends AttrRepoConf> clazz =
150                                 (Class<? extends AttrRepoConf>) ClassUtils.resolveClassName(
151                                         conf.getModelObject(), ClassUtils.getDefaultClassLoader());
152 
153                         attrRepo.setConf(clazz.getConstructor().newInstance());
154                         attrRepoConfClass.setObject(clazz);
155                     } catch (Exception e) {
156                         LOG.error("During deserialization", e);
157                     }
158                 }
159             });
160             add(conf);
161         }
162     }
163 
164     protected class Configuration extends WizardStep {
165 
166         private static final long serialVersionUID = -785981096328637758L;
167 
168         Configuration(final AttrRepoTO attrRepo) {
169             add(new BeanPanel<>("bean", new PropertyModel<>(attrRepo, "conf"), pageRef).setRenderBodyOnly(true));
170         }
171     }
172 
173     protected static final class Mapping extends WizardStep {
174 
175         private static final long serialVersionUID = 3454904947720856253L;
176 
177         Mapping(final AttrRepoTO attrRepo) {
178             setTitleModel(Model.of("Mapping"));
179             setSummaryModel(Model.of(StringUtils.EMPTY));
180             add(new AttrRepoMappingPanel("mapping", attrRepo));
181         }
182     }
183 }