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.commons.lang3.StringUtils;
24  import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
25  import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
26  import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
27  import org.apache.syncope.client.console.wizards.WizardMgtPanel;
28  import org.apache.syncope.client.ui.commons.Constants;
29  import org.apache.syncope.common.lib.to.AnyObjectTO;
30  import org.apache.syncope.common.lib.to.AnyTO;
31  import org.apache.syncope.common.lib.to.GroupTO;
32  import org.apache.syncope.common.lib.to.RelationshipTO;
33  import org.apache.syncope.common.lib.to.UserTO;
34  import org.apache.syncope.common.lib.types.AnyEntitlement;
35  import org.apache.wicket.AttributeModifier;
36  import org.apache.wicket.PageReference;
37  import org.apache.wicket.ajax.AjaxEventBehavior;
38  import org.apache.wicket.ajax.AjaxRequestTarget;
39  import org.apache.wicket.markup.html.WebMarkupContainer;
40  import org.apache.wicket.markup.html.basic.Label;
41  import org.apache.wicket.markup.html.list.ListItem;
42  import org.apache.wicket.markup.html.list.ListView;
43  import org.apache.wicket.model.Model;
44  import org.apache.wicket.model.ResourceModel;
45  
46  public final class RelationshipViewPanel extends WizardMgtPanel<RelationshipTO> {
47  
48      private static final long serialVersionUID = -7510529471158257903L;
49  
50      private ActionLinksTogglePanel<RelationshipTO> togglePanel;
51  
52      private final ListView<RelationshipTO> relationshipsList;
53  
54      private RelationshipViewPanel(
55              final String id,
56              final List<RelationshipTO> relationships,
57              final AnyTO anyTO,
58              final boolean reuseItem,
59              final boolean wizardInModal) {
60  
61          super(id, wizardInModal);
62  
63          WebMarkupContainer header = new WebMarkupContainer("header");
64          header.add(new Label("header_left_end", getString("left.end")));
65          header.add(new Label("header_relationship", new ResourceModel("relationship")));
66          header.add(new Label("header_right_end", new ResourceModel("right.end")));
67          addInnerObject(header);
68  
69          relationshipsList = new ListView<>("relationships", relationships) {
70  
71              private static final long serialVersionUID = 4983556433071042668L;
72  
73              @Override
74              protected void populateItem(final ListItem<RelationshipTO> relationshipItem) {
75                  RelationshipTO relationshipTO = relationshipItem.getModelObject();
76                  buildRowLabels(relationshipItem, relationshipTO, anyTO);
77  
78                  ActionsPanel<RelationshipTO> action = new ActionsPanel<>("action", new Model<>(relationshipTO));
79                  action.add(new ActionLink<>() {
80  
81                      private static final long serialVersionUID = 5207800927605869051L;
82  
83                      @Override
84                      public void onClick(final AjaxRequestTarget target, final RelationshipTO modelObject) {
85                          relationships.remove(modelObject);
86                          relationshipsList.remove(relationshipItem);
87                          target.add(RelationshipViewPanel.this);
88                      }
89                  }, ActionLink.ActionType.DELETE, AnyEntitlement.UPDATE.getFor(anyTO.getType()), true).hideLabel();
90  
91                  if (togglePanel != null) {
92                      relationshipItem.add(new AttributeModifier("style", "cursor: pointer;"));
93                      relationshipItem.add(new AjaxEventBehavior(Constants.ON_CLICK) {
94  
95                          private static final long serialVersionUID = -9027652037484739586L;
96  
97                          @Override
98                          protected String findIndicatorId() {
99                              return StringUtils.EMPTY;
100                         }
101 
102                         @Override
103                         protected void onEvent(final AjaxRequestTarget target) {
104                             togglePanel.toggleWithContent(target, action, relationshipTO);
105                         }
106                     });
107                 }
108 
109                 if (togglePanel == null) {
110                     relationshipItem.add(action);
111                 } else {
112                     relationshipItem.add(new ActionsPanel<>("action", new Model<>(relationshipTO)).
113                             setVisible(false).setEnabled(false));
114                 }
115             }
116         };
117         relationshipsList.setOutputMarkupId(true);
118         relationshipsList.setReuseItems(reuseItem);
119         relationshipsList.setRenderBodyOnly(true);
120 
121         addInnerObject(relationshipsList);
122     }
123 
124     private static void buildRowLabels(
125             final ListItem<RelationshipTO> row,
126             final RelationshipTO relationshipTO,
127             final AnyTO anyTO) {
128 
129         boolean isLeftRelation = relationshipTO.getEnd() == RelationshipTO.End.LEFT;
130 
131         String anyName = anyTO instanceof UserTO userTO
132                 ? userTO.getUsername()
133                 : anyTO instanceof GroupTO groupTO
134                         ? groupTO.getName()
135                         : AnyObjectTO.class.cast(anyTO).getName();
136 
137         row.add(new Label("relationship", relationshipTO.getType()));
138         Label leftEnd = new Label("left_end", isLeftRelation
139                 ? "%s %s".formatted(anyTO.getType(), anyName)
140                 : "%s %s".formatted(relationshipTO.getOtherEndType(), relationshipTO.getOtherEndName()));
141 
142         Label rightEnd = new Label("right_end", isLeftRelation
143                 ? "%s %s".formatted(relationshipTO.getOtherEndType(), relationshipTO.getOtherEndName())
144                 : "%s %s".formatted(anyTO.getType(), anyName));
145 
146         if (anyTO.getKey() != null && anyTO.getKey().equals(relationshipTO.getOtherEndKey())) {
147             setBold(leftEnd, rightEnd);
148         } else {
149             setBold(isLeftRelation ? leftEnd : rightEnd);
150         }
151         row.add(leftEnd, rightEnd);
152     }
153 
154     private static void setBold(final Label... labels) {
155         for (Label label : labels) {
156             label.add(new AttributeModifier("style", "font-weight: bold;"));
157         }
158     }
159 
160     public static class Builder extends WizardMgtPanel.Builder<RelationshipTO> {
161 
162         private static final long serialVersionUID = -3643771352897992172L;
163 
164         private List<RelationshipTO> relationships;
165 
166         private AnyTO anyTO;
167 
168         private boolean reuseItem = true;
169 
170         public Builder(final PageReference pageRef) {
171             super(pageRef);
172             this.relationships = null;
173             this.anyTO = null;
174         }
175 
176         public RelationshipViewPanel.Builder setAnyTO(final AnyTO anyTO) {
177             this.anyTO = anyTO;
178             return this;
179         }
180 
181         public RelationshipViewPanel.Builder setRelationships(final List<RelationshipTO> relationships) {
182             this.relationships = relationships;
183             return this;
184         }
185 
186         public RelationshipViewPanel.Builder addItem(final RelationshipTO item) {
187             if (item == null) {
188                 return this;
189             }
190 
191             if (this.relationships == null) {
192                 this.relationships = new ArrayList<>();
193             }
194 
195             this.relationships.add(item);
196             return this;
197         }
198 
199         public RelationshipViewPanel.Builder setReuseItem(final boolean reuseItem) {
200             this.reuseItem = reuseItem;
201             return this;
202         }
203 
204         @Override
205         protected WizardMgtPanel<RelationshipTO> newInstance(final String id, final boolean wizardInModal) {
206             return new RelationshipViewPanel(id, relationships, anyTO, reuseItem, wizardInModal);
207         }
208     }
209 }