1   package org.daisy.pipeline.css.impl;
2   
3   import java.util.regex.Pattern;
4   
5   import javax.xml.parsers.DocumentBuilderFactory;
6   import javax.xml.XMLConstants;
7   
8   import org.daisy.pipeline.datatypes.DatatypeService;
9   import org.daisy.pipeline.datatypes.ValidationResult;
10  
11  import org.osgi.service.component.annotations.Component;
12  
13  import org.w3c.dom.Attr;
14  import org.w3c.dom.Document;
15  import org.w3c.dom.Element;
16  
17  @Component(
18  	name = "org.daisy.pipeline.css.impl.StylesheetParametersDatatypeService",
19  	service = {
20  		DatatypeService.class
21  	}
22  )
23  public class StylesheetParametersDatatypeService extends DatatypeService {
24  
25  	private final Pattern pattern;
26  	private Document xmlDefinition = null;
27  
28  	protected StylesheetParametersDatatypeService() {
29  		super("stylesheet-parameters");
30  		pattern = StylesheetParametersParser.asRegex();
31  	}
32  
33  	public ValidationResult validate(String content) {
34  		if (pattern.matcher(content).matches())
35  			return ValidationResult.valid();
36  		else
37  			return ValidationResult.notValid(
38  				"'" + content + "' does not match the regular expression pattern /" + pattern + "/");
39  	}
40  
41  	public Document asDocument() throws Exception {
42  		if (xmlDefinition == null) {
43  			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
44  			                                     .getDOMImplementation().createDocument(null, "data", null);
45  			Element data = doc.getDocumentElement();
46  			Attr type = doc.createAttribute("type");
47  			type.setValue("string");
48  			data.setAttributeNode(type);
49  			Element documentation = (Element)data.appendChild(
50  				doc.createElementNS("http://relaxng.org/ns/compatibility/annotations/1.0",
51  				                    "documentation"));
52  			Attr lang = doc.createAttributeNS(XMLConstants.XML_NS_URI, "lang");
53  			lang.setValue("en");
54  			documentation.setAttributeNode(lang);
55  			Attr space = doc.createAttributeNS(XMLConstants.XML_NS_URI, "space");
56  			space.setValue("preserve");
57  			documentation.setAttributeNode(space);
58  			documentation.appendChild(doc.createTextNode(
59  				"A Sass map"                                                                         + "\n" +
60  				                                                                                       "\n" +
61  				"A [Sass map](https://sass-lang.com/documentation/values/maps/) is a set of pairs"   + "\n" +
62  				"of keys and values written as:"                                                     + "\n" +
63  				                                                                                       "\n" +
64  				"    (<expression>: <expression>, <expression>: <expression>, ...)"                  + "\n" +
65  				                                                                                       "\n" +
66  				"where the"                                                                          + "\n" +
67  				"[expression](https://sass-lang.com/documentation/syntax/structure#expressions)"     + "\n" +
68  				"before the `:` is the key, and the expression after is the value associated"        + "\n" +
69  				"with that key. The keys must be unique. An empty map is written `()`."));
70  			Element param = (Element)data.appendChild(doc.createElement("param"));
71  			Attr name = doc.createAttribute("name");
72  			name.setValue("pattern");
73  			param.setAttributeNode(name);
74  			param.appendChild(doc.createTextNode("^(" + pattern.pattern().replaceAll("\\(\\?<[^>]+>", "(") + ")$"));
75  			xmlDefinition = doc;
76  		}
77  		return xmlDefinition;
78  	}
79  }