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.enduser.panels;
20  
21  import java.util.List;
22  import org.apache.syncope.client.enduser.SyncopeWebApplication;
23  import org.apache.syncope.client.enduser.commons.EnduserConstants;
24  import org.apache.syncope.client.enduser.layout.UserFormLayoutInfo;
25  import org.apache.syncope.client.enduser.panels.any.DerAttrs;
26  import org.apache.syncope.client.enduser.panels.any.Details;
27  import org.apache.syncope.client.enduser.panels.any.Groups;
28  import org.apache.syncope.client.enduser.panels.any.PlainAttrs;
29  import org.apache.syncope.client.enduser.panels.any.Resources;
30  import org.apache.syncope.client.enduser.panels.any.VirAttrs;
31  import org.apache.syncope.client.enduser.panels.captcha.CaptchaPanel;
32  import org.apache.syncope.client.ui.commons.panels.CardPanel;
33  import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper;
34  import org.apache.syncope.common.lib.Attr;
35  import org.apache.syncope.common.lib.to.AnyTO;
36  import org.apache.syncope.common.lib.to.GroupableRelatableTO;
37  import org.apache.syncope.common.lib.to.UserTO;
38  import org.apache.wicket.PageReference;
39  
40  public abstract class AnyFormPanel extends AbstractAnyFormPanel<UserWrapper> {
41  
42      private static final long serialVersionUID = -2720486919461006370L;
43  
44      protected final List<String> anyTypeClasses;
45  
46      protected CaptchaPanel<Void> captcha;
47  
48      protected UserFormLayoutInfo formLayoutInfo;
49  
50      public AnyFormPanel(final String id,
51              final UserTO anyTO,
52              final List<String> anyTypeClasses,
53              final UserFormLayoutInfo formLayoutInfo,
54              final PageReference pageReference) {
55  
56          super(id, new UserWrapper(anyTO), pageReference);
57  
58          this.formLayoutInfo = formLayoutInfo;
59          this.anyTypeClasses = anyTypeClasses;
60      }
61  
62      @SuppressWarnings("unchecked")
63      public AnyFormPanel(final String id,
64              final UserWrapper wrapper,
65              final List<String> anyTypeClasses,
66              final UserFormLayoutInfo formLayoutInfo,
67              final PageReference pageReference) {
68  
69          super(id, wrapper, pageReference);
70  
71          this.formLayoutInfo = formLayoutInfo;
72          this.anyTypeClasses = anyTypeClasses;
73      }
74  
75      protected Details<UserTO> addOptionalDetailsPanel(final UserWrapper modelObject) {
76          Details<UserTO> details = new Details<>(EnduserConstants.CONTENT_PANEL, pageRef);
77          details.setOutputMarkupId(true);
78          return details;
79      }
80  
81      @Override
82      protected void buildLayout(final UserWrapper modelObject) {
83          form.add(new CardPanel.Builder<>()
84                  .setName("details")
85                  .setComponent(addOptionalDetailsPanel(modelObject))
86                  .isVisible(formLayoutInfo.isDetailsManagement()).build("userDetailsPanelCard"));
87  
88          Groups groups = new Groups(EnduserConstants.CONTENT_PANEL, modelObject);
89          setOutputMarkupId(true);
90  
91          form.add(new CardPanel.Builder<Groups>()
92                  .setName("groups")
93                  .setComponent(groups)
94                  .isVisible(formLayoutInfo.isGroups()).build("groupsPanelCard"));
95  
96          PlainAttrs plainAttrs = new PlainAttrs(EnduserConstants.CONTENT_PANEL,
97                  modelObject, anyTypeClasses, formLayoutInfo.getWhichPlainAttrs());
98          plainAttrs.setOutputMarkupId(true);
99  
100         form.add(new CardPanel.Builder<PlainAttrs>()
101                 .setName("attributes.plain")
102                 .setComponent(plainAttrs)
103                 .isVisible(formLayoutInfo.isPlainAttrs() && plainAttrs.isPanelVisible()).build("plainAttrsPanelCard"));
104 
105         DerAttrs derAttrs = new DerAttrs(EnduserConstants.CONTENT_PANEL,
106                 modelObject, anyTypeClasses, formLayoutInfo.getWhichDerAttrs());
107         derAttrs.setOutputMarkupId(true);
108 
109         form.add(new CardPanel.Builder<DerAttrs>()
110                 .setName("attributes.derived")
111                 .setComponent(derAttrs)
112                 .isVisible(formLayoutInfo.isVirAttrs() && derAttrs.isPanelVisible()).build("derAttrsPanelCard"));
113 
114         VirAttrs virAttrs = new VirAttrs(EnduserConstants.CONTENT_PANEL,
115                 modelObject, anyTypeClasses, formLayoutInfo.getWhichVirAttrs());
116         virAttrs.setOutputMarkupId(true);
117 
118         form.add(new CardPanel.Builder<VirAttrs>()
119                 .setName("attributes.virtual")
120                 .setComponent(virAttrs)
121                 .isVisible(formLayoutInfo.isVirAttrs() && virAttrs.isPanelVisible()).build("virAttrsPanelCard"));
122 
123         Resources resources = new Resources(EnduserConstants.CONTENT_PANEL, modelObject);
124         resources.setOutputMarkupId(true);
125 
126         form.add(new CardPanel.Builder<Resources>()
127                 .setName("resources")
128                 .setComponent(resources)
129                 .isVisible(formLayoutInfo.isResources()).build("resourcesPanelCard"));
130 
131         // add captcha
132         captcha = new CaptchaPanel<>(EnduserConstants.CONTENT_PANEL);
133         captcha.setOutputMarkupPlaceholderTag(true);
134 
135         form.add(new CardPanel.Builder<CaptchaPanel<Void>>()
136                 .setName("captcha")
137                 .setComponent(captcha)
138                 .isVisible(SyncopeWebApplication.get().isCaptchaEnabled()).build("captchaPanelCard"));
139     }
140 
141     protected void fixPlainAndVirAttrs(final AnyTO updated, final AnyTO original) {
142         // re-add to the updated object any missing plain or virtual attribute (compared to original): this to cope with
143         // form layout, which might have not included some plain or virtual attributes
144         for (Attr plainAttr : original.getPlainAttrs()) {
145             if (updated.getPlainAttr(plainAttr.getSchema()).isEmpty()) {
146                 updated.getPlainAttrs().add(plainAttr);
147             }
148         }
149         for (Attr virAttr : original.getVirAttrs()) {
150             if (updated.getVirAttr(virAttr.getSchema()).isEmpty()) {
151                 updated.getVirAttrs().add(virAttr);
152             }
153         }
154 
155         if (updated instanceof GroupableRelatableTO && original instanceof GroupableRelatableTO) {
156             GroupableRelatableTO.class
157                     .cast(original).getMemberships().forEach(oMemb -> {
158                 GroupableRelatableTO.class
159                         .cast(updated).getMembership(oMemb.getGroupKey()).ifPresent(uMemb -> {
160                     oMemb.getPlainAttrs()
161                             .stream().
162                             filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isEmpty()).
163                             forEach(attr -> uMemb.getPlainAttrs().add(attr));
164                     oMemb.getVirAttrs()
165                             .stream().
166                             filter(attr -> uMemb.getVirAttr(attr.getSchema()).isEmpty()).
167                             forEach(attr -> uMemb.getVirAttrs().add(attr));
168                 }
169                 );
170             });
171         }
172 
173         // remove from the updated object any plain or virtual attribute without values, thus triggering for removal in
174         // the generated patch
175         updated.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty());
176         updated.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty());
177         if (updated instanceof GroupableRelatableTO) {
178             GroupableRelatableTO.class.cast(updated).getMemberships().forEach(memb -> {
179                 memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty());
180                 memb.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty());
181             });
182         }
183     }
184 }