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.io.Serializable;
22  import java.util.Collections;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.stream.Collectors;
27  import org.apache.syncope.client.console.PreferenceManager;
28  import org.apache.syncope.client.console.SyncopeConsoleSession;
29  import org.apache.syncope.client.console.pages.BasePage;
30  import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
31  import org.apache.syncope.client.ui.commons.Constants;
32  import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
33  import org.apache.syncope.common.lib.search.SearchableFields;
34  import org.apache.syncope.common.lib.to.AnyObjectTO;
35  import org.apache.syncope.common.lib.to.AnyTO;
36  import org.apache.syncope.common.lib.to.GroupTO;
37  import org.apache.syncope.common.lib.to.UserTO;
38  import org.apache.syncope.common.lib.types.AnyTypeKind;
39  import org.apache.wicket.PageReference;
40  import org.apache.wicket.ajax.AjaxRequestTarget;
41  import org.apache.wicket.markup.html.WebMarkupContainer;
42  import org.apache.wicket.model.IModel;
43  import org.apache.wicket.model.LoadableDetachableModel;
44  import org.apache.wicket.model.PropertyModel;
45  import org.apache.wicket.model.util.ListModel;
46  
47  /**
48   * Modal window with Display attributes form.
49   *
50   * @param <T> can be {@link AnyTO} or {@link org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper}
51   */
52  public abstract class DisplayAttributesModalPanel<T extends Serializable> extends AbstractModalPanel<T> {
53  
54      private static final long serialVersionUID = -4274117450918385110L;
55  
56      /**
57       * Max allowed selections.
58       */
59      private static final int MAX_SELECTIONS = 9;
60  
61      private final List<String> selectedDetails;
62  
63      private final List<String> selectedPlainSchemas;
64  
65      private final List<String> selectedDerSchemas;
66  
67      protected final String type;
68  
69      public DisplayAttributesModalPanel(
70              final BaseModal<T> modal,
71              final PageReference pageRef,
72              final List<String> pSchemaNames,
73              final List<String> dSchemaNames,
74              final String type) {
75  
76          super(modal, pageRef);
77          this.type = type;
78  
79          Collections.sort(pSchemaNames);
80          Collections.sort(dSchemaNames);
81  
82          final IModel<List<String>> fnames = new LoadableDetachableModel<>() {
83  
84              private static final long serialVersionUID = 5275935387613157437L;
85  
86              @Override
87              protected List<String> load() {
88                  return SearchableFields.get(DisplayAttributesModalPanel.getTOClass(type))
89                          .keySet().stream().sorted().collect(Collectors.toList());
90              }
91          };
92  
93          IModel<List<String>> psnames = new LoadableDetachableModel<>() {
94  
95              private static final long serialVersionUID = 5275935387613157437L;
96  
97              @Override
98              protected List<String> load() {
99                  return pSchemaNames;
100             }
101         };
102 
103         IModel<List<String>> dsnames = new LoadableDetachableModel<>() {
104 
105             private static final long serialVersionUID = 5275935387613157437L;
106 
107             @Override
108             protected List<String> load() {
109                 return dSchemaNames;
110             }
111         };
112 
113         selectedDetails = PreferenceManager.getList(DisplayAttributesModalPanel.getPrefDetailView(type));
114         selectedPlainSchemas = PreferenceManager.getList(DisplayAttributesModalPanel.getPrefPlainAttributeView(type));
115         selectedDerSchemas = PreferenceManager.getList(DisplayAttributesModalPanel.getPrefDerivedAttributeView(type));
116 
117         // remove old schemas from selected lists
118         selectedPlainSchemas.retainAll(pSchemaNames);
119         selectedDerSchemas.retainAll(dSchemaNames);
120 
121         WebMarkupContainer container = new WebMarkupContainer("container");
122         container.setOutputMarkupId(true);
123         add(container);
124 
125         AjaxPalettePanel<String> details = new AjaxPalettePanel.Builder<String>().
126                 setAllowOrder(true).
127                 setAllowMoveAll(true).
128                 build("details",
129                         new PropertyModel<>(this, "selectedDetails"),
130                         new ListModel<>(fnames.getObject()));
131         details.hideLabel();
132         details.setOutputMarkupId(true);
133         container.add(details);
134 
135         AjaxPalettePanel<String> plainSchemas = new AjaxPalettePanel.Builder<String>().
136                 setAllowOrder(true).
137                 setAllowMoveAll(true).
138                 build("plainSchemas",
139                         new PropertyModel<>(this, "selectedPlainSchemas"),
140                         new ListModel<>(psnames.getObject()));
141         plainSchemas.hideLabel();
142         plainSchemas.setOutputMarkupId(true);
143         container.add(plainSchemas);
144 
145         AjaxPalettePanel<String> derSchemas = new AjaxPalettePanel.Builder<String>().
146                 setAllowOrder(true).
147                 setAllowMoveAll(true).
148                 build("derSchemas",
149                         new PropertyModel<>(this, "selectedDerSchemas"),
150                         new ListModel<>(dsnames.getObject()));
151         derSchemas.hideLabel();
152         derSchemas.setOutputMarkupId(true);
153         container.add(derSchemas);
154     }
155 
156     @Override
157     public void onSubmit(final AjaxRequestTarget target) {
158         if (selectedDetails.size() + selectedPlainSchemas.size() + selectedDerSchemas.size() > MAX_SELECTIONS) {
159             SyncopeConsoleSession.get().error(getString("tooManySelections"));
160             onError(target);
161         } else {
162             Map<String, List<String>> prefs = new HashMap<>();
163             prefs.put(DisplayAttributesModalPanel.getPrefDetailView(type), selectedDetails);
164             prefs.put(DisplayAttributesModalPanel.getPrefPlainAttributeView(type), selectedPlainSchemas);
165             prefs.put(DisplayAttributesModalPanel.getPrefDerivedAttributeView(type), selectedDerSchemas);
166             PreferenceManager.setList(prefs);
167 
168             SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
169             modal.close(target);
170             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
171         }
172     }
173 
174     public static final String getPrefDetailView(final String type) {
175         return String.format(Constants.PREF_ANY_DETAILS_VIEW, type);
176     }
177 
178     public static final String getPrefPlainAttributeView(final String type) {
179         return String.format(Constants.PREF_ANY_PLAIN_ATTRS_VIEW, type);
180     }
181 
182     public static final String getPrefDerivedAttributeView(final String type) {
183         return String.format(Constants.PREF_ANY_DER_ATTRS_VIEW, type);
184     }
185 
186     public static final Class<? extends AnyTO> getTOClass(final String type) {
187         if (type.equalsIgnoreCase(AnyTypeKind.USER.name())) {
188             return UserTO.class;
189         }
190         if (type.equalsIgnoreCase(AnyTypeKind.GROUP.name())) {
191             return GroupTO.class;
192         }
193         return AnyObjectTO.class;
194     }
195 }