1. Project Clover database mar. avr. 16 2024 08:19:06 CEST
  2. Package org.devacfr.maven.skins.reflow.model

File NavSideMenu.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart6.png
65% of files have more coverage

Code metrics

14
53
11
1
263
120
19
0,36
4,82
11
1,73

Classes

Class Line # Actions
68 53 0% 19 34
0.564102656,4%
 

Contributing tests

This file is covered by 11 tests. .

Source view

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.devacfr.maven.skins.reflow.model;
20   
21    import javax.annotation.Nonnull;
22    import javax.annotation.Nullable;
23   
24    import java.util.ArrayList;
25    import java.util.Collections;
26    import java.util.List;
27   
28    import com.google.common.base.Strings;
29    import com.google.common.collect.Lists;
30    import org.apache.commons.lang3.builder.ToStringBuilder;
31    import org.codehaus.plexus.util.xml.Xpp3Dom;
32    import org.devacfr.maven.skins.reflow.ISkinConfig;
33    import org.devacfr.maven.skins.reflow.SkinConfigTool;
34    import org.devacfr.maven.skins.reflow.Xpp3Utils;
35   
36    import static java.util.Objects.requireNonNull;
37   
38    /**
39    * Represents the navside menu component used in document page.
40    * <p>
41    * A sample configuration would be like that:
42    * </p>
43    *
44    * <pre>
45    * {@code
46    * <custom>
47    * <reflowSkin>
48    * <pages>
49    * <document type="doc">
50    * <menu name="Documentation" selectFirstOnExpand="true">
51    * <item name="Get Started" href="get-started.html" />
52    * <item name="Layouts">
53    * <item name="Overview" href="layouts.html" />
54    * <item name="Body" href="body.html" />
55    * </item>
56    * <item name="Migration" href="migration.html" />
57    * </menu>
58    * </document>
59    * </pages>
60    * </reflowSkin>
61    * </custom>
62    * }∂
63    * </pre>
64    *
65    * @author Christophe Friederich
66    * @since 2.0
67    */
 
68    public class NavSideMenu extends BsComponent {
69   
70    /** */
71    private static final String COMPONENT = "navside-menu";
72   
73    /** */
74    private static final String MENU_COMPONENT = "menu";
75   
76    /** */
77    private String name;
78   
79    /** */
80    private List<SideNavMenuItem> items;
81   
82    /** */
83    private boolean selectFirstOnExpand = false;
84   
85    /**
86    * Find all {@link SideNavMenuItem sidenav menu items} declared in all document pages.
87    *
88    * @param config
89    * a config (can <b>not</b> be {@code null}).
90    * @return Returns a list of all all {@link SideNavMenuItem sidenav menu items} declared in all document pages
91    * (returns list can <b>not</b> be {@code null}).
92    */
 
93  17 toggle @Nonnull
94    public static List<SideNavMenuItem> findAllSideNavMenuItems(@Nonnull final ISkinConfig config) {
95  17 requireNonNull(config);
96  17 final Xpp3Dom pagesNode = Xpp3Utils.getFirstChild(config.getGlobalProperties(), "pages", config.getNamespace());
97  17 if (pagesNode == null) {
98  10 return Collections.emptyList();
99    }
100  7 final Xpp3Dom[] pages = pagesNode.getChildren();
101  7 final List<SideNavMenuItem> includePages = new ArrayList<>();
102  7 for (final Xpp3Dom page : pages) {
103  19 final String type = page.getAttribute("type");
104  19 if ("doc".equals(type)) {
105    // This allows preventing accidental reuse of child page in other module of
106    // project
107  7 final String projectId = page.getAttribute("project");
108  7 if (!Strings.isNullOrEmpty(projectId) && !projectId.equals(config.getProjectId())) {
109  0 continue;
110    }
111  7 final Xpp3Dom menu = page.getChild(MENU_COMPONENT);
112  7 if (menu == null) {
113  0 continue;
114    }
115  7 final String pageName = page.getName();
116    // create a flatten list containing all menuItem.
117  7 addMenuItemRecursively(includePages, config, menu, pageName, true);
118    }
119    }
120  7 return includePages;
121    }
122   
123    /**
124    * Default constructor.
125    *
126    * @param config
127    * a config (can <b>not</b> be {@code null}).
128    */
 
129  1 toggle public NavSideMenu(@Nonnull final ISkinConfig config) {
130  1 super("navside");
131  1 requireNonNull(config);
132  1 final Xpp3Dom pageNode = config.getPageProperties();
133  1 final Xpp3Dom menu = pageNode.getChild(MENU_COMPONENT);
134  1 final List<SideNavMenuItem> items = Lists.newArrayList();
135  1 if (menu != null) {
136  0 final String pageName = pageNode.getName();
137  0 addMenuItemRecursively(items, config, menu, pageName, false);
138   
139  0 this.withName(menu.getAttribute("name"))
140    .withItems(items)
141    .withSelectFirstOnSelect(
142    config.getAttributeValue(MENU_COMPONENT, "selectFirstOnExpand", Boolean.class, true));
143  0 this.setTheme(config.getAttributeValue(COMPONENT, "theme", String.class, "light"));
144  0 this.setBackground(config.getAttributeValue(COMPONENT, "background", String.class, "light"));
145  0 this.setCssClass(config.getAttributeValue(COMPONENT, "cssClass", String.class, null));
146    }
147  1 this.addCssOptions("m-sidenav-enabled");
148  1 if (isSelectFirstOnExpand()) {
149  0 this.addCssOptions("m-sidenav-select-first-on-select");
150    }
151    }
152   
153    /**
154    * Gets the name of menu displayed on top of navside menu.
155    *
156    * @return Returns a {@link String} representing the name of menu.
157    */
 
158  0 toggle @Nullable public String getName() {
159  0 return name;
160    }
161   
162    /**
163    * Sets the name of menu displayed on top of navside menu.
164    *
165    * @param name
166    * the name to use.
167    * @return Returns the fluent instance.
168    */
 
169  0 toggle protected NavSideMenu withName(final String name) {
170  0 this.name = name;
171  0 return this;
172    }
173   
174    /**
175    * Gets the indicating whether menu contains a least one menu item.
176    *
177    * @return Returns {@code true} whether menu contains a least one menu item, otherwise returns {@code false}.
178    */
 
179  0 toggle public boolean isHasItems() {
180  0 return items != null && !items.isEmpty();
181    }
182   
183    /**
184    * @return Returns the {@link List} of {@link SideNavMenuItem} containing in {@code <menu> element}.
185    */
 
186  0 toggle @Nonnull
187    public List<SideNavMenuItem> getItems() {
188  0 return items;
189    }
190   
191    /**
192    * Sets the {@link List} of {@link SideNavMenuItem}.
193    *
194    * @param items
195    * list of items to use.
196    * @return Returns the fluent instance.
197    */
 
198  0 toggle protected NavSideMenu withItems(final List<SideNavMenuItem> items) {
199  0 this.items = items;
200  0 return this;
201    }
202   
203    /**
204    * Gets the indicating whether the first sub menu item should be selected when a dropdown menu item is selected and
205    * should expand.
206    *
207    * @return Returns {@code true} whether the first sub menu item should be selected when a dropdown menu item is
208    * selected and expanded, otherwise returns {@code false}.
209    */
 
210  1 toggle public boolean isSelectFirstOnExpand() {
211  1 return selectFirstOnExpand;
212    }
213   
214    /**
215    * Sets the indicating whether the first sub menu item should be selected when a dropdown menu item is selected and
216    * should expand.
217    *
218    * @param selectFirstOnExpand
219    * a value to use.
220    * @return Returns the fluent instance.
221    */
 
222  0 toggle protected NavSideMenu withSelectFirstOnSelect(final boolean selectFirstOnExpand) {
223  0 this.selectFirstOnExpand = selectFirstOnExpand;
224  0 return this;
225    }
226   
227    /**
228    * {@inheritDoc}
229    */
 
230  0 toggle @Override
231    public String toString() {
232  0 return ToStringBuilder.reflectionToString(this);
233    }
234   
235    /**
236    * @param menuItems
237    * @param parentNode
238    * @param pageName
239    * @param flatten
240    */
 
241  28 toggle private static void addMenuItemRecursively(@Nonnull final List<SideNavMenuItem> menuItems,
242    @Nonnull final ISkinConfig config,
243    @Nonnull final Xpp3Dom parentNode,
244    @Nonnull final String pageName,
245    final boolean flatten) {
246  28 for (final Xpp3Dom item : Xpp3Utils.getChildrenNodes(parentNode, "item")) {
247  21 final String href = item.getAttribute("href");
248  21 final SideNavMenuItem menuItem = new SideNavMenuItem().withName(item.getAttribute("name"))
249    .withParent(pageName)
250    .withHref(config.relativeLink(href))
251    .withSlugName(SkinConfigTool.slugFilename(href))
252    .withIcon(item.getAttribute("icon"));
253  21 menuItems.add(menuItem);
254  21 if (flatten) {
255  21 addMenuItemRecursively(menuItems, config, item, pageName, true);
256    } else {
257  0 final List<SideNavMenuItem> list = new ArrayList<>();
258  0 menuItem.withItems(list);
259  0 addMenuItemRecursively(list, config, item, pageName, false);
260    }
261    }
262    }
263    }