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

File Context.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart9.png
10% of files have more coverage

Code metrics

18
65
13
1
290
153
26
0,4
5
13
2

Classes

Class Line # Actions
Context 55 65 0% 26 13
0.864583386,5%
 

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.context;
20   
21    import javax.annotation.Nonnull;
22   
23    import java.io.IOException;
24    import java.util.List;
25    import java.util.Map;
26    import java.util.Optional;
27   
28    import com.google.common.collect.ImmutableMap;
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.HtmlTool;
33    import org.devacfr.maven.skins.reflow.ISkinConfig;
34    import org.devacfr.maven.skins.reflow.model.Component;
35    import org.devacfr.maven.skins.reflow.model.Footer;
36    import org.devacfr.maven.skins.reflow.model.NavSideMenu;
37    import org.devacfr.maven.skins.reflow.model.Navbar;
38    import org.devacfr.maven.skins.reflow.model.ScrollTop;
39    import org.devacfr.maven.skins.reflow.model.SideNavMenuItem;
40    import org.devacfr.maven.skins.reflow.snippet.SnippetContext;
41    import org.devacfr.maven.skins.reflow.snippet.SnippetParser;
42    import org.slf4j.Logger;
43    import org.slf4j.LoggerFactory;
44   
45    import static java.util.Objects.requireNonNull;
46   
47    /**
48    * The base class of all contexts depending type of page.
49    *
50    * @author Christophe Friederich
51    * @since 2.0
52    * @param <T>
53    * type of inherrit context object.
54    */
 
55    public abstract class Context<T extends Context<?>> extends Component {
56   
57    /**
58    * map containing the equivalence of font awesome characters with image found in report pages.
59    */
60    private static final Map<String, String> ICON_REPLACEMENTS = ImmutableMap.<String, String> builder()
61    .put("img[src$=images/add.gif]", "<i class=\"fas fa-plus\"></i>")
62    .put("img[src$=images/remove.gif]", "<i class=\"fas fa-minus\"></i>")
63    .put("img[src$=images/fix.gif]", "<i class=\"fas fa-wrench\"></i>")
64    .put("img[src$=images/update.gif]", "<i class=\"fas fa-redo\"></i>")
65    .put("img[src$=images/icon_help_sml.gif]", "<i class=\"fas fa-question\"></i>")
66    .put("img[src$=images/icon_success_sml.gif]", "<i class=\"fas fa-check-circle\"></i>")
67    .put("img[src$=images/icon_warning_sml.gif]", "<i class=\"fas fa-exclamation-triangle\"></i>")
68    .put("img[src$=images/icon_error_sml.gif]", "<i class=\"fas fa-exclamation-circle\"></i>")
69    .put("img[src$=images/icon_info_sml.gif]", "<i class=\"fas fa-info\"></i>")
70    .build();
71   
72    /** */
73    private static final Logger LOGGER = LoggerFactory.getLogger(Context.class);
74   
75    /** */
76    private ContextType type;
77   
78    /** */
79    private final Navbar navbar;
80   
81    /** */
82    private final Footer footer;
83   
84    /** */
85    private final ScrollTop scrollTop;
86   
87    /**
88    * Build a context depending of current type of page.
89    *
90    * @param config
91    * a config (can not be {@code null}).
92    * @return Returns a new instance of {@link Context} depending of current page.
93    */
 
94  17 toggle @Nonnull
95    public static Context<?> buildContext(@Nonnull final ISkinConfig config) {
96  17 requireNonNull(config);
97   
98  17 ContextType type = ContextType.page;
99  17 final List<SideNavMenuItem> allSideNaveMenuItems = NavSideMenu.findAllSideNavMenuItems(config);
100  17 if (LOGGER.isTraceEnabled()) {
101  0 LOGGER.trace("findAllSideNavMenuItems: " + allSideNaveMenuItems);
102    }
103  17 final Xpp3Dom pageProperties = config.getPageProperties();
104  17 final String fileId = config.getFileId();
105   
106  17 if (pageProperties != null) {
107  10 if (pageProperties.getAttribute("type") != null) {
108  3 type = ContextType.valueOf(pageProperties.getAttribute("type"));
109    }
110   
111    // frame type whether page associates to document page
112  10 if (allSideNaveMenuItems.stream().filter(item -> fileId.equals(item.getSlugName())).count() > 0) {
113  1 type = ContextType.frame;
114    }
115    }
116    // if (type== null) {
117    // type = ContextType.page;
118    // }
119  17 Context<?> context = null;
120  17 switch (type) {
121  1 case doc:
122  1 context = new DocumentContext(config);
123  1 break;
124   
125  1 case frame:
126    // search the parent document page
127  1 final Optional<SideNavMenuItem> menuItem = allSideNaveMenuItems.stream()
128    .filter(item -> fileId.equals(item.getSlugName()))
129    .findFirst();
130  1 final SideNavMenuItem item = menuItem.get();
131  1 final String documentParent = item.getParent();
132  1 context = new FrameContext(config, documentParent);
133  1 break;
134  2 case body:
135  2 context = new BodyContext(config);
136  2 break;
137  13 case page:
138  0 default:
139  13 context = new PageContext(config);
140  13 break;
141    }
142  17 return context;
143    }
144   
145    /**
146    * Default constructor.
147    *
148    * @param config
149    * a config (can not be {@code null}).
150    * @param type
151    * the type of context (can not be {@code null}).
152    */
 
153  17 toggle public Context(@Nonnull final ISkinConfig config, @Nonnull final ContextType type) {
154  17 requireNonNull(config);
155  17 this.withType(requireNonNull(type));
156  17 this.navbar = new Navbar(config);
157  17 this.scrollTop = new ScrollTop(config);
158  17 this.footer = new Footer(config);
159   
160  17 this.initialize(config);
161   
162    // the ordering is important for execute preRender method
163  17 this.addChildren(this.navbar, this.scrollTop, this.footer);
164    }
165   
166    /**
167    * Allows to initialize the context.
168    *
169    * @param config
170    * a config (can not be {@code null}).
171    */
 
172  15 toggle protected void initialize(@Nonnull final ISkinConfig config) {
173    // enable AnchorJS
174  15 if (!config.not("anchorJS")) {
175  15 this.addCssOptions("anchorjs-enabled");
176    }
177    }
178   
179    /**
180    * Allows to execute action before rendering of component.
181    *
182    * @param skinConfig
183    * a config (can <b>not</b> be {@code null}).
184    * @return Returns the {@link String} representing the transformed body content.
185    * @since 2.1
186    */
 
187  6 toggle public String preRender(@Nonnull final ISkinConfig skinConfig) {
188  6 return onPreRender(skinConfig, getBodyContent(skinConfig));
189    }
190   
 
191  5 toggle @Override
192    protected String onPreRender(final @Nonnull ISkinConfig skinConfig, final @Nonnull String bodyContent) {
193  5 final HtmlTool htmlTool = getHtmlTool(skinConfig);
194  5 String content = bodyContent;
195  5 if (!skinConfig.not("imgLightbox")) {
196    // lightbox is enabled by default, so check for false and negate
197  5 content = htmlTool.setAttr(content,
198    "a[href$=jpg], a[href$=JPG], a[href$=jpeg], a[href$=JPEG], "
199    + "a[href$=png], a[href$=gif],a[href$=bmp]:has(img)",
200    "data-lightbox",
201    "page");
202    }
203   
204  5 if (!skinConfig.not("html5Anchor")) {
205    // HTML5-style anchors are enabled by default, so check for false and negate
206  5 content = htmlTool.headingAnchorToId(content);
207    }
208   
209  5 if (!skinConfig.not("bootstrapCss")) {
210    // Bootstrap CSS class conversion is enabled by default, so check for false and
211    // negate
212  5 content = htmlTool
213    .addClass(content, "table.bodyTable", Lists.newArrayList("table", "table-striped", "table-hover"));
214    // image is responsive by default
215  5 content = htmlTool.addClass(content, "img", Lists.newArrayList("img-fluid"));
216  5 content = htmlTool.fixTableHeads(content);
217    }
218   
219  5 if (!skinConfig.not("bootstrapIcons")) {
220    // Bootstrap Icons are enabled by default, so check for false and negate
221  5 content = htmlTool.replaceAll(content, ICON_REPLACEMENTS);
222    }
223   
224    // The <tt> tag is not supported in HTML5 (see
225    // https://www.w3schools.com/tags/tag_tt.asp).
226  5 content = htmlTool.replaceWith(content, "tt", "<code class=\"literal\">");
227  5 return super.onPreRender(skinConfig, content);
228    }
229   
 
230  0 toggle public String renderSnippets(final ISkinConfig skinConfig, final String bodyContent) throws IOException {
231  0 final SnippetContext snippetContext = new SnippetParser().parse(skinConfig, bodyContent);
232  0 return snippetContext.html();
233    }
234   
235    /**
236    * @return Returns the {@link Navbar}.
237    */
 
238  3 toggle public Navbar getNavbar() {
239  3 return navbar;
240    }
241   
242    /**
243    * @return Returns the {@link ScrollTop}.
244    */
 
245  3 toggle public ScrollTop getScrollTop() {
246  3 return scrollTop;
247    }
248   
249    /**
250    * @return Returns the {@link Footer}.
251    */
 
252  3 toggle public Footer getFooter() {
253  3 return footer;
254    }
255   
256    /**
257    * Sets the type of context.
258    *
259    * @param type
260    * the of context.
261    * @return Returns the fluent instance context.
262    */
 
263  17 toggle protected T withType(final ContextType type) {
264  17 this.type = type;
265  17 return self();
266    }
267   
268    /**
269    * @return Returns the type of context of page.
270    */
 
271  2 toggle public String getType() {
272  2 return type.name();
273    }
274   
275    /**
276    * @return Returns the fluent instance.
277    */
 
278  17 toggle @SuppressWarnings("unchecked")
279    protected T self() {
280  17 return (T) this;
281    }
282   
283    /**
284    * {@inheritDoc}
285    */
 
286  0 toggle @Override
287    public String toString() {
288  0 return ToStringBuilder.reflectionToString(this);
289    }
290    }