ThymeleafV3TemplateDetector.java

1
package fr.sii.ogham.template.thymeleaf.v3;
2
3
import java.io.BufferedReader;
4
import java.io.IOException;
5
import java.io.InputStream;
6
import java.io.InputStreamReader;
7
import java.util.regex.Pattern;
8
9
import org.slf4j.Logger;
10
import org.slf4j.LoggerFactory;
11
12
import fr.sii.ogham.core.exception.resource.ResourceResolutionException;
13
import fr.sii.ogham.core.exception.template.EngineDetectionException;
14
import fr.sii.ogham.core.resource.Resource;
15
import fr.sii.ogham.core.resource.path.ResourcePath;
16
import fr.sii.ogham.core.resource.resolver.ResourceResolver;
17
import fr.sii.ogham.core.template.context.Context;
18
import fr.sii.ogham.core.template.detector.TemplateEngineDetector;
19
20
/**
21
 * Detector that reads the content of the template. If the template contains the
22
 * Thymeleaf namespace (http://www.thymeleaf.org) then the detector returns
23
 * true. Otherwise it returns false.
24
 * 
25
 * @author Aurélien Baudet
26
 *
27
 */
28
public class ThymeleafV3TemplateDetector implements TemplateEngineDetector {
29
	private static final Logger LOG = LoggerFactory.getLogger(ThymeleafV3TemplateDetector.class);
30
31
	/**
32
	 * The pattern to search into the template
33
	 */
34
	private static final Pattern NAMESPACE_PATTERN = Pattern.compile("xmlns[^=]+=\\s*\"http://www.thymeleaf.org\"");
35
36
	/**
37
	 * The pattern to search into the template
38
	 */
39
	private static final Pattern VARIABLE_PATTERN = Pattern.compile("(\\[\\[\\$\\{[^}]+\\}\\]\\])|(\\[\\(\\$\\{[^}]+\\}\\)\\])");
40
41
	/**
42
	 * The pattern to search into the template
43
	 */
44
	private static final Pattern TEXT_TEMPLATE_TH_PATTERN = Pattern.compile("(\\[#\\s*th:)");
45
46
	/**
47
	 * The template resolver used to find the template
48
	 */
49
	private final ResourceResolver resolver;
50
51
	public ThymeleafV3TemplateDetector(ResourceResolver resolver) {
52
		super();
53
		this.resolver = resolver;
54
	}
55
56
	@Override
57
	public boolean canParse(ResourcePath template, Context ctx) throws EngineDetectionException {
58
		LOG.debug("Checking if Thymeleaf can handle the template {}", template);
59
		Resource resolvedTemplate = getTemplate(template);
60 1 1. canParse : negated conditional → RUN_ERROR
		if (resolvedTemplate == null) {
61 1 1. canParse : replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::canParse → NO_COVERAGE
			return false;
62
		}
63
		try (BufferedReader br = new BufferedReader(new InputStreamReader(resolvedTemplate.getInputStream()))) {
64
			boolean isThymeleafTemplate = isThymeleafTemplate(br);
65 1 1. canParse : negated conditional → RUN_ERROR
			if (isThymeleafTemplate) {
66
				LOG.debug("The template {} contains the namespace http://www.thymeleaf.org. Thymeleaf can be used", template);
67
			} else {
68
				LOG.debug("The template {} doesn't contain the namespace http://www.thymeleaf.org. Thymeleaf can't be used", template);
69
			}
70 2 1. canParse : negated conditional → RUN_ERROR
2. canParse : negated conditional → RUN_ERROR
			return isThymeleafTemplate || isEmptyTemplate(resolvedTemplate);
71
		} catch (IOException e) {
72
			throw new EngineDetectionException("Failed to detect because template can't be read by thymeleaf", e);
73
		}
74
	}
75
76
	private static boolean isThymeleafTemplate(BufferedReader br) throws IOException {
77
		String line;
78
		do {
79
			line = br.readLine();
80 4 1. isThymeleafTemplate : negated conditional → RUN_ERROR
2. isThymeleafTemplate : negated conditional → RUN_ERROR
3. isThymeleafTemplate : negated conditional → RUN_ERROR
4. isThymeleafTemplate : negated conditional → RUN_ERROR
			if (line != null && (containsThymeleafNamespace(line) || containsThymeleafVariables(line) || containsThymeleafDirectives(line))) {
81 1 1. isThymeleafTemplate : replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::isThymeleafTemplate → RUN_ERROR
				return true;
82
			}
83 1 1. isThymeleafTemplate : negated conditional → RUN_ERROR
		} while (line != null);
84 1 1. isThymeleafTemplate : replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::isThymeleafTemplate → RUN_ERROR
		return false;
85
	}
86
	
87
	private static boolean isEmptyTemplate(Resource template) throws IOException {
88
		try (InputStream stream = template.getInputStream()) {
89 1 1. isEmptyTemplate : negated conditional → RUN_ERROR
			return stream.read() == -1;
90
		}
91
	}
92
93
	private static boolean containsThymeleafNamespace(String line) {
94 2 1. containsThymeleafNamespace : replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafNamespace → RUN_ERROR
2. containsThymeleafNamespace : replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafNamespace → RUN_ERROR
		return NAMESPACE_PATTERN.matcher(line).find();
95
	}
96
97
	private static boolean containsThymeleafVariables(String line) {
98 2 1. containsThymeleafVariables : replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafVariables → RUN_ERROR
2. containsThymeleafVariables : replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafVariables → RUN_ERROR
		return VARIABLE_PATTERN.matcher(line).find();
99
	}
100
101
	private static boolean containsThymeleafDirectives(String line) {
102 2 1. containsThymeleafDirectives : replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafDirectives → RUN_ERROR
2. containsThymeleafDirectives : replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafDirectives → RUN_ERROR
		return TEXT_TEMPLATE_TH_PATTERN.matcher(line).find();
103
	}
104
105
	private Resource getTemplate(ResourcePath templateName) {
106
		try {
107 1 1. getTemplate : replaced return value with null for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::getTemplate → RUN_ERROR
			return resolver.getResource(templateName);
108
		} catch (ResourceResolutionException e) {
109
			LOG.trace("Thymeleaf detector can't be applied because {} couldn't be resolved", templateName, e);
110
			return null;
111
		}
112
	}
113
114
}

Mutations

60

1.1
Location : canParse
Killed by :
negated conditional → RUN_ERROR

61

1.1
Location : canParse
Killed by :
replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::canParse → NO_COVERAGE

65

1.1
Location : canParse
Killed by :
negated conditional → RUN_ERROR

70

1.1
Location : canParse
Killed by :
negated conditional → RUN_ERROR

2.2
Location : canParse
Killed by :
negated conditional → RUN_ERROR

80

1.1
Location : isThymeleafTemplate
Killed by :
negated conditional → RUN_ERROR

2.2
Location : isThymeleafTemplate
Killed by :
negated conditional → RUN_ERROR

3.3
Location : isThymeleafTemplate
Killed by :
negated conditional → RUN_ERROR

4.4
Location : isThymeleafTemplate
Killed by :
negated conditional → RUN_ERROR

81

1.1
Location : isThymeleafTemplate
Killed by :
replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::isThymeleafTemplate → RUN_ERROR

83

1.1
Location : isThymeleafTemplate
Killed by :
negated conditional → RUN_ERROR

84

1.1
Location : isThymeleafTemplate
Killed by :
replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::isThymeleafTemplate → RUN_ERROR

89

1.1
Location : isEmptyTemplate
Killed by :
negated conditional → RUN_ERROR

94

1.1
Location : containsThymeleafNamespace
Killed by :
replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafNamespace → RUN_ERROR

2.2
Location : containsThymeleafNamespace
Killed by :
replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafNamespace → RUN_ERROR

98

1.1
Location : containsThymeleafVariables
Killed by :
replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafVariables → RUN_ERROR

2.2
Location : containsThymeleafVariables
Killed by :
replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafVariables → RUN_ERROR

102

1.1
Location : containsThymeleafDirectives
Killed by :
replaced boolean return with true for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafDirectives → RUN_ERROR

2.2
Location : containsThymeleafDirectives
Killed by :
replaced boolean return with false for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::containsThymeleafDirectives → RUN_ERROR

107

1.1
Location : getTemplate
Killed by :
replaced return value with null for fr/sii/ogham/template/thymeleaf/v3/ThymeleafV3TemplateDetector::getTemplate → RUN_ERROR

Active mutators

Tests examined


Report generated by PIT 1.13.1