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.panels;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
24  import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
25  import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
26  import org.apache.syncope.common.lib.scim.SCIMComplexConf;
27  import org.apache.syncope.common.lib.scim.SCIMConf;
28  import org.apache.syncope.common.lib.scim.SCIMUserAddressConf;
29  import org.apache.syncope.common.lib.scim.SCIMUserConf;
30  import org.apache.syncope.common.lib.scim.SCIMUserNameConf;
31  import org.apache.syncope.common.lib.scim.types.AddressCanonicalType;
32  import org.apache.syncope.common.lib.scim.types.EmailCanonicalType;
33  import org.apache.syncope.common.lib.scim.types.IMCanonicalType;
34  import org.apache.syncope.common.lib.scim.types.PhoneNumberCanonicalType;
35  import org.apache.syncope.common.lib.scim.types.PhotoCanonicalType;
36  import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSettings;
37  import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
38  import org.apache.wicket.markup.html.WebMarkupContainer;
39  import org.apache.wicket.markup.html.basic.Label;
40  import org.apache.wicket.model.Model;
41  import org.apache.wicket.model.PropertyModel;
42  import org.apache.wicket.model.util.ListModel;
43  import org.slf4j.Logger;
44  import org.slf4j.LoggerFactory;
45  
46  public class SCIMConfUserPanel extends SCIMConfTabPanel {
47  
48      protected static final Logger LOG = LoggerFactory.getLogger(SCIMConfUserPanel.class);
49  
50      private static final long serialVersionUID = 8747864142447220523L;
51  
52      private final SCIMUserConf scimUserConf;
53  
54      public SCIMConfUserPanel(final String id, final SCIMConf scimConf) {
55          super(id);
56  
57          if (scimConf.getUserConf() == null) {
58              scimConf.setUserConf(new SCIMUserConf());
59          }
60          if (scimConf.getUserConf().getName() == null) {
61              scimConf.getUserConf().setName(new SCIMUserNameConf());
62          }
63          scimUserConf = scimConf.getUserConf();
64  
65          final AutoCompleteSettings settings = new AutoCompleteSettings();
66          settings.setShowCompleteListOnFocusGain(true);
67          settings.setShowListOnEmptyInput(true);
68          settings.setCssClassName("custom-autocomplete-box");
69  
70          AjaxTextFieldPanel externalIdPanel = new AjaxTextFieldPanel("externalId", "externalId",
71                  new PropertyModel<>("externalId", "externalId") {
72  
73              private static final long serialVersionUID = -6427731218492117883L;
74  
75              @Override
76              public String getObject() {
77                  return scimUserConf.getExternalId();
78              }
79  
80              @Override
81              public void setObject(final String object) {
82                  scimUserConf.setExternalId(object);
83              }
84          });
85          externalIdPanel.setChoices(userPlainSchemas.getObject());
86  
87          AjaxTextFieldPanel displayNamePanel = new AjaxTextFieldPanel("displayName", "displayName",
88                  new PropertyModel<>("displayName", "displayName") {
89  
90              private static final long serialVersionUID = -6427731218492117883L;
91  
92              @Override
93              public String getObject() {
94                  return scimUserConf.getDisplayName();
95              }
96  
97              @Override
98              public void setObject(final String object) {
99                  scimUserConf.setDisplayName(object);
100             }
101         });
102         displayNamePanel.setChoices(userPlainSchemas.getObject());
103 
104         AjaxTextFieldPanel localePanel = new AjaxTextFieldPanel("locale", "locale",
105                 new PropertyModel<>("locale", "locale") {
106 
107             private static final long serialVersionUID = -6427731218492117883L;
108 
109             @Override
110             public String getObject() {
111                 return scimUserConf.getLocale();
112             }
113 
114             @Override
115             public void setObject(final String object) {
116                 scimUserConf.setLocale(object);
117             }
118         });
119         localePanel.setChoices(userPlainSchemas.getObject());
120 
121         AjaxTextFieldPanel nickNamePanel = new AjaxTextFieldPanel("nickName", "nickName",
122                 new PropertyModel<>("nickName", "nickName") {
123 
124             private static final long serialVersionUID = -6427731218492117883L;
125 
126             @Override
127             public String getObject() {
128                 return scimUserConf.getNickName();
129             }
130 
131             @Override
132             public void setObject(final String object) {
133                 scimUserConf.setNickName(object);
134             }
135         });
136         nickNamePanel.setChoices(userPlainSchemas.getObject());
137 
138         AjaxTextFieldPanel preferredLanguagePanel = new AjaxTextFieldPanel("preferredLanguage", "preferredLanguage",
139                 new PropertyModel<>("preferredLanguage", "preferredLanguage") {
140 
141             private static final long serialVersionUID = -6427731218492117883L;
142 
143             @Override
144             public String getObject() {
145                 return scimUserConf.getPreferredLanguage();
146             }
147 
148             @Override
149             public void setObject(final String object) {
150                 scimUserConf.setPreferredLanguage(object);
151             }
152         });
153         preferredLanguagePanel.setChoices(userPlainSchemas.getObject());
154 
155         AjaxTextFieldPanel profileUrlPanel = new AjaxTextFieldPanel("profileUrl", "profileUrl",
156                 new PropertyModel<>("profileUrl", "profileUrl") {
157 
158             private static final long serialVersionUID = -6427731218492117883L;
159 
160             @Override
161             public String getObject() {
162                 return scimUserConf.getProfileUrl();
163             }
164 
165             @Override
166             public void setObject(final String object) {
167                 scimUserConf.setProfileUrl(object);
168             }
169         });
170         profileUrlPanel.setChoices(userPlainSchemas.getObject());
171 
172         AjaxTextFieldPanel timezonePanel = new AjaxTextFieldPanel("timezone", "timezone",
173                 new PropertyModel<>("timezone", "timezone") {
174 
175             private static final long serialVersionUID = -6427731218492117883L;
176 
177             @Override
178             public String getObject() {
179                 return scimUserConf.getTimezone();
180             }
181 
182             @Override
183             public void setObject(final String object) {
184                 scimUserConf.setTimezone(object);
185             }
186         });
187         timezonePanel.setChoices(userPlainSchemas.getObject());
188 
189         AjaxTextFieldPanel titlePanel = new AjaxTextFieldPanel("title", "title",
190                 new PropertyModel<>("title", "title") {
191 
192             private static final long serialVersionUID = -6427731218492117883L;
193 
194             @Override
195             public String getObject() {
196                 return scimUserConf.getTitle();
197             }
198 
199             @Override
200             public void setObject(final String object) {
201                 scimUserConf.setTitle(object);
202             }
203         });
204         titlePanel.setChoices(userPlainSchemas.getObject());
205 
206         AjaxTextFieldPanel userTypePanel = new AjaxTextFieldPanel("userType", "userType",
207                 new PropertyModel<>("userType", "userType") {
208 
209             private static final long serialVersionUID = -6427731218492117883L;
210 
211             @Override
212             public String getObject() {
213                 return scimUserConf.getUserType();
214             }
215 
216             @Override
217             public void setObject(final String object) {
218                 scimUserConf.setUserType(object);
219             }
220         });
221         userTypePanel.setChoices(userPlainSchemas.getObject());
222 
223         // name
224         buildNameAccordion();
225 
226         // x509certificates
227         final AjaxTextFieldPanel x509CertificatesPanel = new AjaxTextFieldPanel("panel", "x509CertificatesPanel",
228                 new Model<>(null));
229         x509CertificatesPanel.setChoices(userPlainSchemas.getObject());
230         MultiFieldPanel<String> x509CertificatesMultiPanel = new MultiFieldPanel.Builder<>(
231                 new ListModel<>(scimUserConf.getX509Certificates())).build(
232                 "x509Certificates",
233                 "x509Certificates",
234                 x509CertificatesPanel);
235 
236         // addresses
237         List<SCIMUserAddressConf> addresses = new ArrayList<>();
238         for (AddressCanonicalType canonicalType : AddressCanonicalType.values()) {
239             SCIMUserAddressConf address = scimUserConf.getAddresses().stream().
240                     filter(addressConf -> addressConf.getType().equals(canonicalType)).
241                     findFirst().orElseGet(() -> {
242                         SCIMUserAddressConf empty = new SCIMUserAddressConf();
243                         empty.setType(canonicalType);
244                         return empty;
245                     });
246             buildAddressAccordion(address, canonicalType);
247             addresses.add(address);
248         }
249         scimUserConf.getAddresses().clear();
250         scimUserConf.getAddresses().addAll(addresses);
251 
252         // complex objects
253         buildComplexPanels(scimUserConf.getEmails(), "emailsAccordion", "emails", EmailCanonicalType.values());
254         buildComplexPanels(scimUserConf.getPhoneNumbers(), "phoneNumbersAccordion", "phoneNumbers",
255                 PhoneNumberCanonicalType.values());
256         buildComplexPanels(scimUserConf.getIms(), "imsAccordion", "ims", IMCanonicalType.values());
257         buildComplexPanels(scimUserConf.getPhotos(), "photosAccordion", "photos", PhotoCanonicalType.values());
258 
259         add(externalIdPanel);
260         add(displayNamePanel);
261         add(localePanel);
262         add(nickNamePanel);
263         add(preferredLanguagePanel);
264         add(profileUrlPanel);
265         add(timezonePanel);
266         add(titlePanel);
267         add(userTypePanel);
268 
269         add(x509CertificatesMultiPanel);
270 
271         add(new Label("nameLabel", Model.of("name")));
272         add(new Label("addressesLabel", Model.of("addresses")));
273         add(new Label("emailsLabel", Model.of("emails")));
274         add(new Label("phoneNumbersLabel", Model.of("phoneNumbers")));
275         add(new Label("imsLabel", Model.of("ims")));
276         add(new Label("photosLabel", Model.of("photos")));
277     }
278 
279     private <T extends Enum<?>> void buildComplexPanels(
280             final List<SCIMComplexConf<T>> complexes,
281             final String basePanelId,
282             final String baseTabId,
283             final T[] canonicalTypes) {
284 
285         List<SCIMComplexConf<T>> newElems = new ArrayList<>();
286         for (T canonicalType : canonicalTypes) {
287             SCIMComplexConf<T> complex = complexes.stream().
288                     filter(complexConf -> complexConf.getType().equals(canonicalType)).
289                     findFirst().orElseGet(() -> {
290                         SCIMComplexConf<T> empty = new SCIMComplexConf<>();
291                         empty.setType(canonicalType);
292                         return empty;
293                     });
294             buildComplexAccordion(complex, basePanelId, baseTabId, canonicalType);
295             newElems.add(complex);
296         }
297         complexes.clear();
298         complexes.addAll(newElems);
299     }
300 
301     private void buildNameAccordion() {
302         Accordion accordion = new Accordion("nameAccordion", List.of(new AbstractTab(Model.of("name")) {
303 
304             private static final long serialVersionUID = -5861786415855103549L;
305 
306             @Override
307             public WebMarkupContainer getPanel(final String panelId) {
308                 return buildNameAccordionContent(panelId);
309             }
310 
311         }), Model.of(-1)); // accordion closed at beginning
312         add(accordion.setOutputMarkupId(true));
313     }
314 
315     private void buildAddressAccordion(final SCIMUserAddressConf address, final AddressCanonicalType canonicalType) {
316         Accordion accordion = new Accordion("addressesAccordion_" + address.getType().name(),
317                 List.of(new AbstractTab(Model.of("address." + address.getType().name())) {
318 
319                     private static final long serialVersionUID = -5861786415855103549L;
320 
321                     @Override
322                     public WebMarkupContainer getPanel(final String panelId) {
323                         return buildAddressAccordionContent(address, canonicalType, panelId);
324                     }
325                 }), Model.of(-1)); // accordion closed at beginning
326         add(accordion.setOutputMarkupId(true));
327     }
328 
329     private <T extends Enum<?>> void buildComplexAccordion(
330             final SCIMComplexConf<T> complex,
331             final String basePanelId,
332             final String baseTabId,
333             final T canonicalType) {
334 
335         Accordion accordion = new Accordion(basePanelId + '_' + complex.getType().name(),
336                 List.of(new AbstractTab(Model.of(baseTabId + '.' + complex.getType().name())) {
337 
338                     private static final long serialVersionUID = -5861786415855103549L;
339 
340                     @Override
341                     public WebMarkupContainer getPanel(final String panelId) {
342                         return buildComplexAccordionContent(complex, canonicalType, panelId);
343                     }
344 
345                 }), Model.of(-1)); // accordion closed at beginning
346         add(accordion.setOutputMarkupId(true));
347     }
348 
349     private SCIMConfAccordionContainer buildNameAccordionContent(final String panelId) {
350         List<AjaxTextFieldPanel> panelList = new ArrayList<>();
351 
352         AjaxTextFieldPanel nameFamilyNamePanel = new AjaxTextFieldPanel("accordionContent", "name.familyName",
353                 new PropertyModel<>(scimUserConf.getName(), "accordionContent") {
354 
355             private static final long serialVersionUID = -6427731218492117883L;
356 
357             @Override
358             public String getObject() {
359                 return scimUserConf.getName().getFamilyName();
360             }
361 
362             @Override
363             public void setObject(final String object) {
364                 scimUserConf.getName().setFamilyName(object);
365             }
366         });
367         nameFamilyNamePanel.setChoices(userPlainSchemas.getObject());
368 
369         AjaxTextFieldPanel nameFormattedPanel = new AjaxTextFieldPanel("accordionContent", "name.formatted",
370                 new PropertyModel<>(scimUserConf.getName(), "accordionContent") {
371 
372             private static final long serialVersionUID = -6427731218492117883L;
373 
374             @Override
375             public String getObject() {
376                 return scimUserConf.getName().getFormatted();
377             }
378 
379             @Override
380             public void setObject(final String object) {
381                 scimUserConf.getName().setFormatted(object);
382             }
383         });
384         nameFormattedPanel.setChoices(userPlainSchemas.getObject());
385 
386         AjaxTextFieldPanel nameGivenNamePanel = new AjaxTextFieldPanel("accordionContent", "name.givenName",
387                 new PropertyModel<>(scimUserConf.getName(), "accordionContent") {
388 
389             private static final long serialVersionUID = -6427731218492117883L;
390 
391             @Override
392             public String getObject() {
393                 return scimUserConf.getName().getGivenName();
394             }
395 
396             @Override
397             public void setObject(final String object) {
398                 scimUserConf.getName().setGivenName(object);
399             }
400         });
401         nameGivenNamePanel.setChoices(userPlainSchemas.getObject());
402 
403         AjaxTextFieldPanel nameHonorificPrefixPanel = new AjaxTextFieldPanel("accordionContent", "name.honorificPrefix",
404                 new PropertyModel<>(scimUserConf.getName(), "accordionContent") {
405 
406             private static final long serialVersionUID = -6427731218492117883L;
407 
408             @Override
409             public String getObject() {
410                 return scimUserConf.getName().getHonorificPrefix();
411             }
412 
413             @Override
414             public void setObject(final String object) {
415                 scimUserConf.getName().setHonorificPrefix(object);
416             }
417         });
418         nameHonorificPrefixPanel.setChoices(userPlainSchemas.getObject());
419 
420         AjaxTextFieldPanel nameHonorificSuffixPanel = new AjaxTextFieldPanel("accordionContent", "name.honorificSuffix",
421                 new PropertyModel<>(scimUserConf.getName(), "accordionContent") {
422 
423             private static final long serialVersionUID = -6427731218492117883L;
424 
425             @Override
426             public String getObject() {
427                 return scimUserConf.getName().getHonorificSuffix();
428             }
429 
430             @Override
431             public void setObject(final String object) {
432                 scimUserConf.getName().setHonorificSuffix(object);
433             }
434         });
435         nameHonorificSuffixPanel.setChoices(userPlainSchemas.getObject());
436 
437         AjaxTextFieldPanel nameMiddleNamePanel = new AjaxTextFieldPanel("accordionContent", "name.middleName",
438                 new PropertyModel<>(scimUserConf.getName(), "accordionContent") {
439 
440             private static final long serialVersionUID = -6427731218492117883L;
441 
442             @Override
443             public String getObject() {
444                 return scimUserConf.getName().getMiddleName();
445             }
446 
447             @Override
448             public void setObject(final String object) {
449                 scimUserConf.getName().setMiddleName(object);
450             }
451         });
452         nameMiddleNamePanel.setChoices(userPlainSchemas.getObject());
453 
454         panelList.add(nameFamilyNamePanel);
455         panelList.add(nameFormattedPanel);
456         panelList.add(nameGivenNamePanel);
457         panelList.add(nameHonorificPrefixPanel);
458         panelList.add(nameHonorificSuffixPanel);
459         panelList.add(nameMiddleNamePanel);
460 
461         return new SCIMConfAccordionContainer(panelId, panelList);
462     }
463 
464     private <T extends Enum<?>> SCIMConfAccordionContainer buildComplexAccordionContent(
465             final SCIMComplexConf<T> complex,
466             final T canonicalType,
467             final String panelId) {
468 
469         List<AjaxTextFieldPanel> panelList = new ArrayList<>();
470         String fieldName = panelId + '.' + canonicalType.name();
471 
472         AjaxTextFieldPanel displayPanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".display",
473                 new PropertyModel<>(complex, "accordionContent") {
474 
475             private static final long serialVersionUID = -6427731218492117883L;
476 
477             @Override
478             public String getObject() {
479                 return complex.getDisplay();
480             }
481 
482             @Override
483             public void setObject(final String object) {
484                 complex.setDisplay(object);
485             }
486         });
487         displayPanel.setChoices(userPlainSchemas.getObject());
488 
489         AjaxTextFieldPanel valuePanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".value",
490                 new PropertyModel<>(complex, "accordionContent") {
491 
492             private static final long serialVersionUID = -6427731218492117883L;
493 
494             @Override
495             public String getObject() {
496                 return complex.getValue();
497             }
498 
499             @Override
500             public void setObject(final String object) {
501                 complex.setValue(object);
502             }
503         });
504         valuePanel.setChoices(userPlainSchemas.getObject());
505 
506         AjaxTextFieldPanel primaryPanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".primary",
507                 new PropertyModel<>(complex, "accordionContent") {
508 
509             private static final long serialVersionUID = -6427731218492117883L;
510 
511             @Override
512             public String getObject() {
513                 return String.valueOf(complex.isPrimary());
514             }
515 
516             @Override
517             public void setObject(final String object) {
518                 complex.setPrimary(Boolean.parseBoolean(object));
519             }
520         });
521         primaryPanel.setChoices(List.of("true", "false"));
522 
523         panelList.add(displayPanel);
524         panelList.add(valuePanel);
525         panelList.add(primaryPanel);
526 
527         return new SCIMConfAccordionContainer(panelId, panelList);
528     }
529 
530     private SCIMConfAccordionContainer buildAddressAccordionContent(
531             final SCIMUserAddressConf address,
532             final AddressCanonicalType canonicalType,
533             final String panelId) {
534 
535         List<AjaxTextFieldPanel> panelList = new ArrayList<>();
536         String fieldName = "addresses." + canonicalType.name();
537 
538         AjaxTextFieldPanel addressCountryPanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".country",
539                 new PropertyModel<>(address, "accordionContent") {
540 
541             private static final long serialVersionUID = -6427731218492117883L;
542 
543             @Override
544             public String getObject() {
545                 return address.getCountry();
546             }
547 
548             @Override
549             public void setObject(final String object) {
550                 address.setCountry(object);
551             }
552         });
553         addressCountryPanel.setChoices(userPlainSchemas.getObject());
554 
555         AjaxTextFieldPanel addressFormattedPanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".formatted",
556                 new PropertyModel<>(address, "accordionContent") {
557 
558             private static final long serialVersionUID = -6427731218492117883L;
559 
560             @Override
561             public String getObject() {
562                 return address.getFormatted();
563             }
564 
565             @Override
566             public void setObject(final String object) {
567                 address.setFormatted(object);
568             }
569         });
570         addressFormattedPanel.setChoices(userPlainSchemas.getObject());
571 
572         AjaxTextFieldPanel addressLocalityPanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".locality",
573                 new PropertyModel<>(address, "accordionContent") {
574 
575             private static final long serialVersionUID = -6427731218492117883L;
576 
577             @Override
578             public String getObject() {
579                 return address.getLocality();
580             }
581 
582             @Override
583             public void setObject(final String object) {
584                 address.setLocality(object);
585             }
586         });
587         addressLocalityPanel.setChoices(userPlainSchemas.getObject());
588 
589         AjaxTextFieldPanel addressRegionPanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".region",
590                 new PropertyModel<>(address, "accordionContent") {
591 
592             private static final long serialVersionUID = -6427731218492117883L;
593 
594             @Override
595             public String getObject() {
596                 return address.getRegion();
597             }
598 
599             @Override
600             public void setObject(final String object) {
601                 address.setRegion(object);
602             }
603         });
604         addressRegionPanel.setChoices(userPlainSchemas.getObject());
605 
606         AjaxTextFieldPanel addressPostalCodePanel =
607                 new AjaxTextFieldPanel("accordionContent", fieldName + ".postalCode",
608                         new PropertyModel<>(address, "accordionContent") {
609 
610                     private static final long serialVersionUID = -6427731218492117883L;
611 
612                     @Override
613                     public String getObject() {
614                         return address.getPostalCode();
615                     }
616 
617                     @Override
618                     public void setObject(final String object) {
619                         address.setPostalCode(object);
620                     }
621                 });
622         addressPostalCodePanel.setChoices(userPlainSchemas.getObject());
623 
624         AjaxTextFieldPanel addressPrimaryPanel = new AjaxTextFieldPanel("accordionContent", fieldName + ".primary",
625                 new PropertyModel<>(address, "accordionContent") {
626 
627             private static final long serialVersionUID = -6427731218492117883L;
628 
629             @Override
630             public String getObject() {
631                 return String.valueOf(address.isPrimary());
632             }
633 
634             @Override
635             public void setObject(final String object) {
636                 address.setPrimary(Boolean.parseBoolean(object));
637             }
638         });
639         addressPrimaryPanel.setChoices(List.of("true", "false"));
640 
641         panelList.add(addressCountryPanel);
642         panelList.add(addressFormattedPanel);
643         panelList.add(addressLocalityPanel);
644         panelList.add(addressRegionPanel);
645         panelList.add(addressPostalCodePanel);
646         panelList.add(addressPrimaryPanel);
647 
648         return new SCIMConfAccordionContainer(panelId, panelList);
649     }
650 }