1 package org
.argeo
.cms
.ui
.internal
.text
;
3 import java
.io
.StringReader
;
4 import java
.text
.MessageFormat
;
5 import java
.util
.Arrays
;
6 import java
.util
.HashMap
;
10 import javax
.xml
.parsers
.SAXParser
;
11 import javax
.xml
.parsers
.SAXParserFactory
;
13 import org
.argeo
.cms
.forms
.FormPageViewer
;
14 import org
.eclipse
.rap
.rwt
.SingletonUtil
;
15 import org
.eclipse
.swt
.widgets
.Widget
;
16 import org
.xml
.sax
.Attributes
;
17 import org
.xml
.sax
.InputSource
;
18 import org
.xml
.sax
.helpers
.DefaultHandler
;
21 * Copy of RAP v2.3 since it is in an internal package.
23 * FIXME made public to enable validation from the {@link FormPageViewer}
25 public class MarkupValidatorCopy
{
27 // Used by Eclipse Scout project
28 public static final String MARKUP_VALIDATION_DISABLED
= "org.eclipse.rap.rwt.markupValidationDisabled";
30 private static final String DTD
= createDTD();
31 private static final Map
<String
, String
[]> SUPPORTED_ELEMENTS
= createSupportedElementsMap();
32 private final SAXParser saxParser
;
34 public static MarkupValidatorCopy
getInstance() {
35 return SingletonUtil
.getSessionInstance(MarkupValidatorCopy
.class);
38 public MarkupValidatorCopy() {
39 saxParser
= createSAXParser();
42 public void validate(String text
) {
43 StringBuilder markup
= new StringBuilder();
45 markup
.append("<html>");
47 markup
.append("</html>");
48 InputSource inputSource
= new InputSource(new StringReader(
51 saxParser
.parse(inputSource
, new MarkupHandler());
52 } catch (RuntimeException exception
) {
54 } catch (Exception exception
) {
55 throw new IllegalArgumentException("Failed to parse markup text",
60 public static boolean isValidationDisabledFor(Widget widget
) {
61 return Boolean
.TRUE
.equals(widget
.getData(MARKUP_VALIDATION_DISABLED
));
64 private static SAXParser
createSAXParser() {
65 SAXParser result
= null;
66 SAXParserFactory parserFactory
= SAXParserFactory
.newInstance();
68 result
= parserFactory
.newSAXParser();
69 } catch (Exception exception
) {
70 throw new RuntimeException("Failed to create SAX parser", exception
);
75 private static String
createDTD() {
76 StringBuilder result
= new StringBuilder();
77 result
.append("<!DOCTYPE html [");
78 result
.append("<!ENTITY quot \""\">");
79 result
.append("<!ENTITY amp \"&\">");
80 result
.append("<!ENTITY apos \"'\">");
81 result
.append("<!ENTITY lt \"<\">");
82 result
.append("<!ENTITY gt \">\">");
83 result
.append("<!ENTITY nbsp \" \">");
84 result
.append("<!ENTITY ensp \" \">");
85 result
.append("<!ENTITY emsp \" \">");
86 result
.append("<!ENTITY ndash \"–\">");
87 result
.append("<!ENTITY mdash \"—\">");
89 return result
.toString();
92 private static Map
<String
, String
[]> createSupportedElementsMap() {
93 Map
<String
, String
[]> result
= new HashMap
<String
, String
[]>();
94 result
.put("html", new String
[0]);
95 result
.put("br", new String
[0]);
96 result
.put("b", new String
[] { "style" });
97 result
.put("strong", new String
[] { "style" });
98 result
.put("i", new String
[] { "style" });
99 result
.put("em", new String
[] { "style" });
100 result
.put("sub", new String
[] { "style" });
101 result
.put("sup", new String
[] { "style" });
102 result
.put("big", new String
[] { "style" });
103 result
.put("small", new String
[] { "style" });
104 result
.put("del", new String
[] { "style" });
105 result
.put("ins", new String
[] { "style" });
106 result
.put("code", new String
[] { "style" });
107 result
.put("samp", new String
[] { "style" });
108 result
.put("kbd", new String
[] { "style" });
109 result
.put("var", new String
[] { "style" });
110 result
.put("cite", new String
[] { "style" });
111 result
.put("dfn", new String
[] { "style" });
112 result
.put("q", new String
[] { "style" });
113 result
.put("abbr", new String
[] { "style", "title" });
114 result
.put("span", new String
[] { "style" });
115 result
.put("img", new String
[] { "style", "src", "width", "height",
117 result
.put("a", new String
[] { "style", "href", "target", "title" });
121 private static class MarkupHandler
extends DefaultHandler
{
124 public void startElement(String uri
, String localName
, String name
,
125 Attributes attributes
) {
126 checkSupportedElements(name
, attributes
);
127 checkSupportedAttributes(name
, attributes
);
128 checkMandatoryAttributes(name
, attributes
);
131 private static void checkSupportedElements(String elementName
,
132 Attributes attributes
) {
133 if (!SUPPORTED_ELEMENTS
.containsKey(elementName
)) {
134 throw new IllegalArgumentException(
135 "Unsupported element in markup text: " + elementName
);
139 private static void checkSupportedAttributes(String elementName
,
140 Attributes attributes
) {
141 if (attributes
.getLength() > 0) {
142 List
<String
> supportedAttributes
= Arrays
143 .asList(SUPPORTED_ELEMENTS
.get(elementName
));
145 String attributeName
= attributes
.getQName(index
);
146 while (attributeName
!= null) {
147 if (!supportedAttributes
.contains(attributeName
)) {
148 String message
= "Unsupported attribute \"{0}\" for element \"{1}\" in markup text";
149 message
= MessageFormat
.format(message
, new Object
[] {
150 attributeName
, elementName
});
151 throw new IllegalArgumentException(message
);
154 attributeName
= attributes
.getQName(index
);
159 private static void checkMandatoryAttributes(String elementName
,
160 Attributes attributes
) {
161 checkIntAttribute(elementName
, attributes
, "img", "width");
162 checkIntAttribute(elementName
, attributes
, "img", "height");
165 private static void checkIntAttribute(String elementName
,
166 Attributes attributes
, String checkedElementName
,
167 String checkedAttributeName
) {
168 if (checkedElementName
.equals(elementName
)) {
169 String attribute
= attributes
.getValue(checkedAttributeName
);
171 Integer
.parseInt(attribute
);
172 } catch (NumberFormatException exception
) {
173 String message
= "Mandatory attribute \"{0}\" for element \"{1}\" is missing or not a valid integer";
174 Object
[] arguments
= new Object
[] { checkedAttributeName
,
175 checkedElementName
};
176 message
= MessageFormat
.format(message
, arguments
);
177 throw new IllegalArgumentException(message
);