]> git.argeo.org Git - gpl/argeo-suite.git/blob - publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/MarkupValidatorCopy.java
Improve terms framework.
[gpl/argeo-suite.git] / publishing / org.argeo.publishing.ui / src / org / argeo / cms / text / MarkupValidatorCopy.java
1 package org.argeo.cms.text;
2
3 import java.io.StringReader;
4 import java.text.MessageFormat;
5 import java.util.Arrays;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 import javax.xml.parsers.SAXParser;
11 import javax.xml.parsers.SAXParserFactory;
12
13 import org.eclipse.rap.rwt.SingletonUtil;
14 import org.eclipse.swt.widgets.Widget;
15 import org.xml.sax.Attributes;
16 import org.xml.sax.InputSource;
17 import org.xml.sax.helpers.DefaultHandler;
18
19 /**
20 * Copy of RAP v2.3 since it is in an internal package.
21 */
22 class MarkupValidatorCopy {
23
24 // Used by Eclipse Scout project
25 public static final String MARKUP_VALIDATION_DISABLED = "org.eclipse.rap.rwt.markupValidationDisabled";
26
27 private static final String DTD = createDTD();
28 private static final Map<String, String[]> SUPPORTED_ELEMENTS = createSupportedElementsMap();
29 private final SAXParser saxParser;
30
31 public static MarkupValidatorCopy getInstance() {
32 return SingletonUtil.getSessionInstance(MarkupValidatorCopy.class);
33 }
34
35 public MarkupValidatorCopy() {
36 saxParser = createSAXParser();
37 }
38
39 public void validate(String text) {
40 StringBuilder markup = new StringBuilder();
41 markup.append(DTD);
42 markup.append("<html>");
43 markup.append(text);
44 markup.append("</html>");
45 InputSource inputSource = new InputSource(new StringReader(markup.toString()));
46 try {
47 saxParser.parse(inputSource, new MarkupHandler());
48 } catch (RuntimeException exception) {
49 throw exception;
50 } catch (Exception exception) {
51 throw new IllegalArgumentException("Failed to parse markup text", exception);
52 }
53 }
54
55 public static boolean isValidationDisabledFor(Widget widget) {
56 return Boolean.TRUE.equals(widget.getData(MARKUP_VALIDATION_DISABLED));
57 }
58
59 private static SAXParser createSAXParser() {
60 SAXParser result = null;
61 SAXParserFactory parserFactory = SAXParserFactory.newInstance();
62 try {
63 result = parserFactory.newSAXParser();
64 } catch (Exception exception) {
65 throw new RuntimeException("Failed to create SAX parser", exception);
66 }
67 return result;
68 }
69
70 private static String createDTD() {
71 StringBuilder result = new StringBuilder();
72 result.append("<!DOCTYPE html [");
73 result.append("<!ENTITY quot \"&#34;\">");
74 result.append("<!ENTITY amp \"&#38;\">");
75 result.append("<!ENTITY apos \"&#39;\">");
76 result.append("<!ENTITY lt \"&#60;\">");
77 result.append("<!ENTITY gt \"&#62;\">");
78 result.append("<!ENTITY nbsp \"&#160;\">");
79 result.append("<!ENTITY ensp \"&#8194;\">");
80 result.append("<!ENTITY emsp \"&#8195;\">");
81 result.append("<!ENTITY ndash \"&#8211;\">");
82 result.append("<!ENTITY mdash \"&#8212;\">");
83 result.append("]>");
84 return result.toString();
85 }
86
87 private static Map<String, String[]> createSupportedElementsMap() {
88 Map<String, String[]> result = new HashMap<String, String[]>();
89 result.put("html", new String[0]);
90 result.put("br", new String[0]);
91 result.put("b", new String[] { "style" });
92 result.put("strong", new String[] { "style" });
93 result.put("i", new String[] { "style" });
94 result.put("em", new String[] { "style" });
95 result.put("sub", new String[] { "style" });
96 result.put("sup", new String[] { "style" });
97 result.put("big", new String[] { "style" });
98 result.put("small", new String[] { "style" });
99 result.put("del", new String[] { "style" });
100 result.put("ins", new String[] { "style" });
101 result.put("code", new String[] { "style" });
102 result.put("samp", new String[] { "style" });
103 result.put("kbd", new String[] { "style" });
104 result.put("var", new String[] { "style" });
105 result.put("cite", new String[] { "style" });
106 result.put("dfn", new String[] { "style" });
107 result.put("q", new String[] { "style" });
108 result.put("abbr", new String[] { "style", "title" });
109 result.put("span", new String[] { "style" });
110 result.put("img", new String[] { "style", "src", "width", "height", "title", "alt" });
111 result.put("a", new String[] { "style", "href", "target", "title" });
112 return result;
113 }
114
115 private static class MarkupHandler extends DefaultHandler {
116
117 @Override
118 public void startElement(String uri, String localName, String name, Attributes attributes) {
119 checkSupportedElements(name, attributes);
120 checkSupportedAttributes(name, attributes);
121 checkMandatoryAttributes(name, attributes);
122 }
123
124 private static void checkSupportedElements(String elementName, Attributes attributes) {
125 if (!SUPPORTED_ELEMENTS.containsKey(elementName)) {
126 throw new IllegalArgumentException("Unsupported element in markup text: " + elementName);
127 }
128 }
129
130 private static void checkSupportedAttributes(String elementName, Attributes attributes) {
131 if (attributes.getLength() > 0) {
132 List<String> supportedAttributes = Arrays.asList(SUPPORTED_ELEMENTS.get(elementName));
133 int index = 0;
134 String attributeName = attributes.getQName(index);
135 while (attributeName != null) {
136 if (!supportedAttributes.contains(attributeName)) {
137 String message = "Unsupported attribute \"{0}\" for element \"{1}\" in markup text";
138 message = MessageFormat.format(message, new Object[] { attributeName, elementName });
139 throw new IllegalArgumentException(message);
140 }
141 index++;
142 attributeName = attributes.getQName(index);
143 }
144 }
145 }
146
147 private static void checkMandatoryAttributes(String elementName, Attributes attributes) {
148 checkIntAttribute(elementName, attributes, "img", "width");
149 checkIntAttribute(elementName, attributes, "img", "height");
150 }
151
152 private static void checkIntAttribute(String elementName, Attributes attributes, String checkedElementName,
153 String checkedAttributeName) {
154 if (checkedElementName.equals(elementName)) {
155 String attribute = attributes.getValue(checkedAttributeName);
156 try {
157 Integer.parseInt(attribute);
158 } catch (NumberFormatException exception) {
159 String message = "Mandatory attribute \"{0}\" for element \"{1}\" is missing or not a valid integer";
160 Object[] arguments = new Object[] { checkedAttributeName, checkedElementName };
161 message = MessageFormat.format(message, arguments);
162 throw new IllegalArgumentException(message);
163 }
164 }
165 }
166
167 }
168
169 }