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 java.util.stream.Collectors;
23  import java.util.stream.StreamSupport;
24  import org.apache.commons.lang3.StringUtils;
25  import org.apache.syncope.client.enduser.BookmarkablePageLinkBuilder;
26  import org.apache.syncope.client.enduser.SyncopeEnduserSession;
27  import org.apache.syncope.client.enduser.SyncopeWebApplication;
28  import org.apache.syncope.client.enduser.layout.SidebarLayout;
29  import org.apache.syncope.client.enduser.pages.BasePage;
30  import org.apache.syncope.client.enduser.pages.Dashboard;
31  import org.apache.syncope.client.enduser.pages.EditChangePassword;
32  import org.apache.syncope.client.enduser.pages.EditSecurityQuestion;
33  import org.apache.syncope.client.enduser.pages.EditUser;
34  import org.apache.syncope.client.ui.commons.annotations.ExtPage;
35  import org.apache.wicket.AttributeModifier;
36  import org.apache.wicket.Component;
37  import org.apache.wicket.Page;
38  import org.apache.wicket.PageReference;
39  import org.apache.wicket.behavior.Behavior;
40  import org.apache.wicket.markup.ComponentTag;
41  import org.apache.wicket.markup.head.IHeaderResponse;
42  import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
43  import org.apache.wicket.markup.html.WebMarkupContainer;
44  import org.apache.wicket.markup.html.basic.Label;
45  import org.apache.wicket.markup.html.link.BookmarkablePageLink;
46  import org.apache.wicket.markup.html.link.Link;
47  import org.apache.wicket.markup.html.list.ListItem;
48  import org.apache.wicket.markup.html.list.ListView;
49  import org.apache.wicket.markup.html.panel.Panel;
50  
51  public class Sidebar extends Panel {
52  
53      private static final long serialVersionUID = 8091307811313529503L;
54  
55      protected WebMarkupContainer dashboardLIContainer;
56  
57      protected WebMarkupContainer profileULContainer;
58  
59      protected WebMarkupContainer profileLIContainer;
60  
61      public Sidebar(
62              final String id,
63              final PageReference pageRef,
64              final List<Class<? extends BasePage>> extPageClasses) {
65  
66          super(id);
67  
68          buildBaseSidebar();
69  
70          // set 'active' menu item for everything but extensions
71          // 1. check if current class is set to top-level menu        
72          WebMarkupContainer containingLI = null;
73          if (dashboardLIContainer.getId().equals(
74                  getLIContainerId(pageRef.getPage().getClass().getSimpleName().toLowerCase()))) {
75  
76              containingLI = dashboardLIContainer;
77          }
78          // 2. if not, check if it is under 'Configuration'
79          if (containingLI == null) {
80              containingLI = (WebMarkupContainer) profileULContainer.get(
81                      getLIContainerId(pageRef.getPage().getClass().getSimpleName().toLowerCase()));
82          }
83          // 3. when found, set CSS coordinates for menu
84          if (containingLI != null) {
85              StreamSupport.stream(containingLI.spliterator(), false).filter(Link.class::isInstance).
86                      forEach(child -> child.add(new Behavior() {
87  
88                  private static final long serialVersionUID = -5775607340182293596L;
89  
90                  @Override
91                  public void onComponentTag(final Component component, final ComponentTag tag) {
92                      tag.append("class", "active", " ");
93                  }
94              }));
95  
96              if (profileULContainer.getId().equals(containingLI.getParent().getId())) {
97                  profileULContainer.add(new Behavior() {
98  
99                      private static final long serialVersionUID = 3109256773218160485L;
100 
101                     @Override
102                     public void renderHead(final Component component, final IHeaderResponse response) {
103                         response.render(OnDomReadyHeaderItem.forScript(
104                                 "$('#profileLink').addClass('active')"));
105                     }
106 
107                     @Override
108                     public void onComponentTag(final Component component, final ComponentTag tag) {
109                         tag.put("class", "nav nav-treeview");
110                         tag.put("style", "display: block;");
111                     }
112                 });
113 
114                 profileLIContainer.add(new Behavior() {
115 
116                     private static final long serialVersionUID = 3109256773218160485L;
117 
118                     @Override
119                     public void onComponentTag(final Component component, final ComponentTag tag) {
120                         tag.put("class", "nav-item has-treeview menu-open");
121                     }
122                 });
123             }
124         }
125 
126         ListView<Class<? extends BasePage>> extPages = new ListView<>("extPages", extPageClasses.stream().
127                 filter(epc -> SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout().
128                 isExtensionEnabled(StringUtils.remove(epc.getAnnotation(ExtPage.class).label(), StringUtils.SPACE))).
129                 collect(Collectors.toList())) {
130 
131             private static final long serialVersionUID = 4949588177564901031L;
132 
133             @Override
134             protected void populateItem(final ListItem<Class<? extends BasePage>> item) {
135                 WebMarkupContainer containingLI = new WebMarkupContainer("extPageLI");
136                 item.add(containingLI);
137 
138                 ExtPage ann = item.getModelObject().getAnnotation(ExtPage.class);
139 
140                 BookmarkablePageLink<Page> link = new BookmarkablePageLink<>("extPage", item.getModelObject());
141 
142                 link.add(new Label("extPageLabel", ann.label()));
143 
144                 if (item.getModelObject().equals(pageRef.getPage().getClass())) {
145                     link.add(new Behavior() {
146 
147                         private static final long serialVersionUID = 1469628524240283489L;
148 
149                         @Override
150                         public void renderHead(final Component component, final IHeaderResponse response) {
151                             response.render(OnDomReadyHeaderItem.forScript(
152                                     "$('#extensionsLink').addClass('active')"));
153                         }
154 
155                         @Override
156                         public void onComponentTag(final Component component, final ComponentTag tag) {
157                             tag.append("class", "active", " ");
158                         }
159                     });
160                 }
161                 containingLI.add(link);
162 
163                 Label extPageIcon = new Label("extPageIcon");
164                 extPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon()));
165                 link.add(extPageIcon);
166             }
167         };
168 
169         add(extPages.setRenderBodyOnly(true).setOutputMarkupId(true));
170     }
171 
172     protected void buildBaseSidebar() {
173         SidebarLayout layout = SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout();
174 
175         dashboardLIContainer = new WebMarkupContainer(getLIContainerId("dashboard"));
176         add(dashboardLIContainer);
177         dashboardLIContainer.add(BookmarkablePageLinkBuilder.build(
178                 "home", SyncopeWebApplication.get().getPageClass("profile", Dashboard.class)));
179 
180         profileLIContainer = new WebMarkupContainer(getLIContainerId("profile"));
181         add(profileLIContainer);
182         profileULContainer = new WebMarkupContainer(getULContainerId("profile"));
183         profileLIContainer.add(profileULContainer);
184         profileLIContainer.setVisible(layout.isEditUserEnabled()
185                 || layout.isPasswordManagementEnabled()
186                 || (layout.isSecurityQuestionManagementEnabled()
187                 && SyncopeEnduserSession.get().getPlatformInfo().isPwdResetRequiringSecurityQuestions()));
188 
189         WebMarkupContainer liContainer = new WebMarkupContainer(getLIContainerId("edituser"));
190         profileULContainer.add(liContainer);
191 
192         liContainer.add(BookmarkablePageLinkBuilder.build("edituser", EditUser.class)).
193                 setVisible(layout.isEditUserEnabled());
194         liContainer = new WebMarkupContainer(getLIContainerId("editchangepassword"));
195         profileULContainer.add(liContainer);
196 
197         liContainer.add(BookmarkablePageLinkBuilder.build("editchangepassword", EditChangePassword.class)).
198                 setVisible(layout.isPasswordManagementEnabled());
199 
200         liContainer = new WebMarkupContainer(getLIContainerId("editsecurityquestion"));
201         profileULContainer.add(liContainer);
202         liContainer.add(BookmarkablePageLinkBuilder.build("editsecurityquestion", EditSecurityQuestion.class));
203         liContainer.setOutputMarkupPlaceholderTag(true);
204         liContainer.setVisible(layout.isSecurityQuestionManagementEnabled()
205                 && SyncopeEnduserSession.get().getPlatformInfo().isPwdResetRequiringSecurityQuestions());
206     }
207 
208     protected String getLIContainerId(final String linkId) {
209         return linkId + "LI";
210     }
211 
212     protected String getULContainerId(final String linkId) {
213         return linkId + "UL";
214     }
215 }