1. Project Clover database mar. janv. 20 2026 12:32:22 CET
  2. Package org.devacfr.maven.skins.reflow.snippet

File SnippetComponent.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart8.png
45% of files have more coverage

Code metrics

8
33
6
2
143
79
12
0,36
5,5
3
2

Classes

Class Line # Actions
SnippetComponent 36 33 0% 12 10
0.7872340778,7%
SnippetComponent.Type 44 0 - 0 0
-1.0 -
 

Contributing tests

This file is covered by 17 tests. .

Source view

1    /*
2    * Copyright 2012-2025 Christophe Friederich
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package org.devacfr.maven.skins.reflow.snippet;
17   
18    import static java.util.Objects.requireNonNull;
19   
20    import javax.annotation.Nonnull;
21    import org.apache.commons.lang3.builder.ToStringBuilder;
22    import org.apache.velocity.context.Context;
23    import org.devacfr.maven.skins.reflow.JsoupUtils;
24    import org.jsoup.nodes.Document;
25    import org.jsoup.nodes.Element;
26    import org.jsoup.select.Elements;
27    import org.slf4j.Logger;
28    import org.slf4j.LoggerFactory;
29   
30    /**
31    * @author Christophe Friederich
32    * @version 2.4
33    * @param <T>
34    * type of component
35    */
 
36    public class SnippetComponent<T extends SnippetComponent<T>> extends Component<T> {
37   
38    /**
39    * type of snippet component
40    *
41    * @author Christophe Friederich
42    * @version 2.4
43    */
 
44    public enum Type {
45    /** web component */
46    webComponent,
47    /** shortcode component */
48    shortcode
49    }
50   
51    private static Logger LOGGER = LoggerFactory.getLogger(SnippetComponent.class);
52   
53    /** */
54    private final Type type;
55   
 
56  53 toggle @Nonnull
57    public static SnippetComponent<?> createSnippet(@Nonnull final Element element,
58    final Component<?> parent,
59    final Type type) {
60  53 requireNonNull(element);
61  53 return new SnippetComponent<>(element, type).withParent(parent);
62    }
63   
64    /**
65    * Constructor.
66    *
67    * @param element
68    * the element
69    */
 
70  53 toggle public SnippetComponent(@Nonnull final Element element, final Type type) {
71  53 super(element);
72  53 this.type = requireNonNull(type);
73  53 this.addAttributes(element.attributes());
74    }
75   
76    /**
77    * Get the type of snippet component.
78    */
 
79  2 toggle @Nonnull
80    public Type getType() {
81  2 return type;
82    }
83   
84    /**
85    * Get the root parent {@link SnippetComponent}.
86    */
 
87  0 toggle @Override
88    protected @Nonnull SnippetComponent<?> getRootParent() {
89  0 return this;
90    }
91   
92    /**
93    * Render the {@link SnippetComponent} between the {@code startElement} and {@code endElement} include.
94    *
95    * @param context
96    * the snippet context to use
97    */
 
98  52 toggle public void render(final SnippetContext context) {
99  52 final Context renderContext = context.getConfig().getVelocityContext();
100  52 final Element element = getElement();
101  52 if (element == null) {
102  0 LOGGER.warn("Element is null for snippet component: {}, file:{}", this, context.getConfig().getFileId());
103  0 return;
104    }
105  52 try {
106  52 final String html = context.renderComponent(this, renderContext);
107   
108  52 final Document doc = JsoupUtils.createHtmlDocument(html);
109  52 final Elements root = doc.body().children();
110  52 if (root.isEmpty()) {
111  0 element.remove();
112  0 return;
113    }
114    // normally, when debug trace is activated
115  52 if (root.size() > 1 && root.first().tagName().equals("pre")) {
116  1 final Element div = new Element("div");
117  1 root.forEach((e) -> div.appendChild(e));
118  1 element.replaceWith(div);
119    } else {
120  51 for (final Element el : root) {
121    // if snippet contains rendered snippet.
122  51 if (context.getParser().hasIncludedSnippetComponent(el)) {
123  1 final SnippetParser parser = context.createChildParser();
124  1 final Element childDoc = parser.parse(context.getConfig(), el.outerHtml()).document();
125  1 childDoc.children().forEach((e) -> element.before(e));
126    } else {
127  50 element.before(el);
128    }
129    }
130  51 element.remove();
131    }
132    } catch (final Exception e) {
133  0 LOGGER.error("Rendering Snippet component failed:{}, file:{}", this, context.getConfig().getFileId());
134  0 throw new RuntimeException(e.getMessage(), e);
135    }
136    }
137   
 
138  91 toggle @Override
139    public String toString() {
140  91 return ToStringBuilder.reflectionToString(this);
141    }
142   
143    }