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

File Component.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart7.png
50% of files have more coverage

Code metrics

24
58
20
1
257
145
33
0,57
2,9
20
1,65

Classes

Class Line # Actions
Component 47 58 0% 33 31
0.696078469,6%
 

Contributing tests

This file is covered by 6 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.snippet;
20   
21    import javax.annotation.Nonnull;
22    import javax.annotation.Nullable;
23   
24    import java.util.Map;
25    import java.util.stream.Collectors;
26   
27    import com.google.common.base.MoreObjects;
28    import com.google.common.collect.Maps;
29    import org.devacfr.maven.skins.reflow.snippet.ComponentToken.Type;
30    import org.jsoup.nodes.Attribute;
31    import org.jsoup.nodes.Attributes;
32    import org.jsoup.nodes.Element;
33    import org.jsoup.nodes.Node;
34    import org.jsoup.nodes.TextNode;
35    import org.jsoup.parser.Tag;
36   
37    import static java.util.Objects.requireNonNull;
38   
39    /**
40    * Base of Snippet component.
41    *
42    * @author Christophe Friederich
43    * @version 2.4
44    * @param <T>
45    * type of component
46    */
 
47    public class Component<T extends Component<T>> {
48   
49    /** */
50    private final Map<String, String> attributes = Maps.newHashMap();
51   
52    /** */
53    private Component<?> parent;
54   
55    /** */
56    private final Components children = new Components();
57   
58    /** */
59    private final Map<String, Components> childrenMap = Maps.newHashMap();
60   
61    /** */
62    private final Node node;
63   
64    /**
65    * @param node
66    * @param parent
67    * @return
68    */
 
69  252 toggle public static Component<?> createComponent(@Nonnull final Node node, final Component<?> parent) {
70  252 return new Component<>(node).withParent(parent).addAttributes(node.attributes());
71    }
72   
73    /**
74    * @param node
75    */
 
76  283 toggle protected Component(@Nonnull final Node node) {
77  283 this.node = requireNonNull(node);
78    }
79   
80    /**
81    * @return the name
82    */
 
83  337 toggle public String getName() {
84  337 return node.nodeName();
85    }
86   
87    /**
88    * @return
89    */
 
90  0 toggle @Nonnull
91    Type getInternalType() {
92  0 return getRootParent().getType();
93    }
94   
95    /**
96    * @return
97    */
 
98  293 toggle public boolean isHtmlTag() {
99  293 return node instanceof TextNode || Tag.isKnownTag(node.nodeName());
100    }
101   
102    /**
103    * @return
104    */
 
105  293 toggle public String getHtml() {
106  293 if (!isHtmlTag()) {
107  115 if (children.isEmpty()) {
108  11 return null;
109    } else {
110  104 return children.html();
111    }
112    } else {
113  178 return this.node.outerHtml();
114    }
115    }
116   
117    /**
118    * @return
119    */
 
120  0 toggle public String getOwnHtml() {
121  0 if (!isHtmlTag()) {
122  0 return null;
123    } else {
124  0 return this.node.outerHtml();
125    }
126    }
127   
128    /**
129    * @return the parent
130    */
 
131  0 toggle public Component<?> getParent() {
132  0 return parent;
133    }
134   
 
135  31 toggle @Nullable protected Element getElement() {
136  31 if (this.node instanceof Element) {
137  31 return (Element) this.node;
138    }
139  0 return null;
140    }
141   
142    /**
143    * @param name
144    * @return
145    */
 
146  268 toggle public Object get(@Nonnull final String name) {
147  268 requireNonNull(name);
148  268 String key = name.toLowerCase();
149    // if attribute
150  268 if (this.attributes.containsKey(key)) {
151  88 return this.attributes.get(key);
152    } else {
153    // is children component?
154    // check if 's' suffix allowing to retrieve children component as list
155  180 if (key.endsWith("s") && !this.childrenMap.containsKey(key)) {
156  8 key = key.substring(0, key.length() - 1);
157  8 if (this.childrenMap.containsKey(key)) {
158  8 return this.childrenMap.get(key);
159    }
160  172 } else if (this.childrenMap.containsKey(key)) {
161  138 final Components value = this.childrenMap.get(key);
162    // TODO i don't know if good idea, but it's works.
163  138 if (value.size() > 1) {
164  0 return value;
165    }
166  138 return value.first();
167    }
168    }
169  34 return null;
170    }
171   
 
172  137 toggle public Map<String, String> getAttrs() {
173  137 return this.attributes;
174    }
175   
176    /**
177    * @return the children
178    */
 
179  283 toggle public Components getChildren() {
180  283 return children;
181    }
182   
 
183  0 toggle public Components getChildren(final String name) {
184  0 final String key = requireNonNull(name).toLowerCase();
185  0 if (this.childrenMap.containsKey(key)) {
186  0 return this.childrenMap.get(key);
187    }
188  0 return Components.empty();
189    }
190   
 
191  254 toggle public T addChild(final Component<?> component) {
192  254 final String key = component.getName();
193  254 Components value = null;
194  254 if (!this.childrenMap.containsKey(key)) {
195  229 value = new Components();
196  229 this.childrenMap.put(key, value);
197    } else {
198  25 value = this.childrenMap.get(key);
199    }
200  254 value.add(component);
201  254 this.children.add(component);
202  254 return self();
203    }
204   
 
205  283 toggle protected T withParent(final Component<?> parent) {
206  283 this.parent = parent;
207  283 return self();
208    }
209   
 
210  0 toggle @Nonnull
211    protected SnippetComponent<?> getRootParent() {
212  0 Component<?> parent = this.parent;
213  0 while (!(parent instanceof SnippetComponent<?>)) {
214  0 parent = parent.parent;
215    }
216  0 return (SnippetComponent<?>) parent;
217    }
218   
219    /**
220    * @param attrs
221    * @return
222    */
 
223  283 toggle protected T addAttributes(@Nonnull final Attributes attrs) {
224  283 attrs.asList().stream().forEach(this::addAttribute);
225  283 return self();
226    }
227   
228    /**
229    * @param attr
230    * @return
231    */
 
232  281 toggle protected T addAttribute(@Nonnull final Attribute attr) {
233  281 this.attributes.put(requireNonNull(attr.getKey()).toLowerCase(), requireNonNull(attr.getValue()));
234  281 return self();
235    }
236   
237    /**
238    * @return
239    */
 
240  1101 toggle @SuppressWarnings("unchecked")
241    protected T self() {
242  1101 return (T) this;
243    }
244   
245    /**
246    * {@inheritDoc}
247    */
 
248  0 toggle @Override
249    public String toString() {
250  0 return MoreObjects.toStringHelper(this)
251    .add("name", this.getName())
252    .add("isHtmlTag", this.isHtmlTag())
253    .add("attributes", this.attributes)
254    .add("children", this.children.stream().map((cpt) -> cpt.getName()).collect(Collectors.toList()))
255    .toString();
256    }
257    }