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.any;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Optional;
26  import java.util.stream.Collectors;
27  import org.apache.commons.collections4.CollectionUtils;
28  import org.apache.commons.collections4.ListUtils;
29  import org.apache.commons.lang3.tuple.Pair;
30  import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
31  import org.apache.syncope.client.ui.commons.ConnIdSpecialName;
32  import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
33  import org.apache.syncope.common.lib.Attr;
34  import org.apache.syncope.common.lib.EntityTOUtils;
35  import org.apache.syncope.common.lib.to.ConnObject;
36  import org.apache.wicket.Component;
37  import org.apache.wicket.behavior.Behavior;
38  import org.apache.wicket.markup.ComponentTag;
39  import org.apache.wicket.markup.html.basic.Label;
40  import org.apache.wicket.markup.html.list.ListItem;
41  import org.apache.wicket.markup.html.list.ListView;
42  import org.apache.wicket.markup.html.panel.Fragment;
43  import org.apache.wicket.markup.html.panel.Panel;
44  import org.apache.wicket.model.IModel;
45  import org.apache.wicket.model.LoadableDetachableModel;
46  import org.apache.wicket.model.Model;
47  import org.apache.wicket.model.util.ListModel;
48  
49  public class ConnObjectPanel extends Panel {
50  
51      private static final long serialVersionUID = -6469290753080058487L;
52  
53      public ConnObjectPanel(
54              final String id,
55              final Pair<IModel<?>, IModel<?>> titles,
56              final Pair<ConnObject, ConnObject> connObjectTOs,
57              final boolean hideLeft) {
58  
59          super(id);
60  
61          final IModel<List<String>> formProps = new LoadableDetachableModel<>() {
62  
63              private static final long serialVersionUID = 5275935387613157437L;
64  
65              @Override
66              protected List<String> load() {
67                  List<Attr> right = new ArrayList<>(connObjectTOs == null || connObjectTOs.getRight() == null
68                      ? List.of()
69                      : connObjectTOs.getRight().getAttrs());
70                  List<Attr> left = new ArrayList<>(connObjectTOs == null || connObjectTOs.getLeft() == null
71                      ? List.of()
72                      : connObjectTOs.getLeft().getAttrs());
73  
74                  List<String> schemas = ListUtils.sum(right.stream().map(Attr::getSchema).collect(Collectors.toList()),
75                      left.stream().map(Attr::getSchema).collect(Collectors.toList()));
76                  Collections.sort(schemas);
77                  return schemas;
78              }
79          };
80  
81          add(new Label("leftTitle", titles.getLeft()).setOutputMarkupPlaceholderTag(true).setVisible(!hideLeft));
82          add(new Label("rightTitle", titles.getRight()));
83  
84          final Map<String, Attr> leftProfile = connObjectTOs == null || connObjectTOs.getLeft() == null
85                  ? null
86                  : EntityTOUtils.buildAttrMap(connObjectTOs.getLeft().getAttrs());
87          final Map<String, Attr> rightProfile = connObjectTOs == null || connObjectTOs.getRight() == null
88                  ? null
89                  : EntityTOUtils.buildAttrMap(connObjectTOs.getRight().getAttrs());
90          ListView<String> propView = new ListView<>("propView", formProps) {
91  
92              private static final long serialVersionUID = 3109256773218160485L;
93  
94              @Override
95              protected void populateItem(final ListItem<String> item) {
96                  final String prop = item.getModelObject();
97  
98                  final Fragment valueFragment;
99                  final Attr left = Optional.ofNullable(leftProfile)
100                     .map(stringAttrMap -> stringAttrMap.get(prop)).orElse(null);
101                 final Attr right = Optional.ofNullable(rightProfile)
102                     .map(profile -> profile.get(prop)).orElse(null);
103 
104                 valueFragment = new Fragment("value", "doubleValue", ConnObjectPanel.this);
105                 valueFragment.add(getValuePanel("leftAttribute", prop, left).
106                     setOutputMarkupPlaceholderTag(true).setVisible(!hideLeft));
107                 valueFragment.add(getValuePanel("rightAttribute", prop, right));
108 
109                 if (left == null || right == null
110                     || (CollectionUtils.isNotEmpty(right.getValues())
111                     && CollectionUtils.isEmpty(left.getValues()))
112                     || (CollectionUtils.isEmpty(right.getValues())
113                     && CollectionUtils.isNotEmpty(left.getValues()))
114                     || (CollectionUtils.isNotEmpty(right.getValues())
115                     && CollectionUtils.isNotEmpty(left.getValues())
116                     && right.getValues().size() != left.getValues().size())
117                     || (CollectionUtils.isNotEmpty(right.getValues())
118                     && CollectionUtils.isNotEmpty(left.getValues())
119                     && !right.getValues().equals(left.getValues()))) {
120 
121                     valueFragment.add(new Behavior() {
122 
123                         private static final long serialVersionUID = 3109256773218160485L;
124 
125                         @Override
126                         public void onComponentTag(final Component component, final ComponentTag tag) {
127                             tag.put("class", "highlight");
128                         }
129                     });
130                 }
131                 item.add(valueFragment);
132             }
133         };
134         add(propView);
135     }
136 
137     /**
138      * Get panel for attribute value (not remote status).
139      *
140      * @param id component id to be replaced with the fragment content.
141      * @param attrTO remote attribute.
142      * @return fragment.
143      */
144     private static Panel getValuePanel(final String id, final String schemaName, final Attr attrTO) {
145         Panel field;
146         if (attrTO == null) {
147             field = new AjaxTextFieldPanel(id, schemaName, new Model<>());
148         } else if (CollectionUtils.isEmpty(attrTO.getValues())) {
149             field = new AjaxTextFieldPanel(id, schemaName, new Model<>());
150         } else if (ConnIdSpecialName.PASSWORD.equals(schemaName)) {
151             field = new AjaxTextFieldPanel(id, schemaName, new Model<>("********"));
152         } else if (attrTO.getValues().size() == 1) {
153             field = new AjaxTextFieldPanel(id, schemaName, new Model<>(attrTO.getValues().get(0)));
154         } else {
155             field = new MultiFieldPanel.Builder<>(new ListModel<>(attrTO.getValues())).build(
156                     id,
157                     schemaName,
158                     new AjaxTextFieldPanel("panel", schemaName, new Model<>()));
159         }
160 
161         field.setEnabled(false);
162         return field;
163     }
164 }