1 package org
.argeo
.cms
.ui
.forms
;
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
.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
;
20 * Copy of RAP v2.3 since it is in an internal package.
22 class MarkupValidatorCopy
{
24 // Used by Eclipse Scout project
25 public static final String MARKUP_VALIDATION_DISABLED
= "org.eclipse.rap.rwt.markupValidationDisabled";
27 private static final String DTD
= createDTD();
28 private static final Map
<String
, String
[]> SUPPORTED_ELEMENTS
= createSupportedElementsMap();
29 private final SAXParser saxParser
;
31 public static MarkupValidatorCopy
getInstance() {
32 return SingletonUtil
.getSessionInstance(MarkupValidatorCopy
.class);
35 public MarkupValidatorCopy() {
36 saxParser
= createSAXParser();
39 public void validate(String text
) {
40 StringBuilder markup
= new StringBuilder();
42 markup
.append("<html>");
44 markup
.append("</html>");
45 InputSource inputSource
= new InputSource(new StringReader(markup
.toString()));
47 saxParser
.parse(inputSource
, new MarkupHandler());
48 } catch (RuntimeException exception
) {
50 } catch (Exception exception
) {
51 throw new IllegalArgumentException("Failed to parse markup text", exception
);
55 public static boolean isValidationDisabledFor(Widget widget
) {
56 return Boolean
.TRUE
.equals(widget
.getData(MARKUP_VALIDATION_DISABLED
));
59 private static SAXParser
createSAXParser() {
60 SAXParser result
= null;
61 SAXParserFactory parserFactory
= SAXParserFactory
.newInstance();
63 result
= parserFactory
.newSAXParser();
64 } catch (Exception exception
) {
65 throw new RuntimeException("Failed to create SAX parser", exception
);
70 private static String
createDTD() {
71 StringBuilder result
= new StringBuilder();
72 result
.append("<!DOCTYPE html [");
73 result
.append("<!ENTITY quot \""\">");
74 result
.append("<!ENTITY amp \"&\">");
75 result
.append("<!ENTITY apos \"'\">");
76 result
.append("<!ENTITY lt \"<\">");
77 result
.append("<!ENTITY gt \">\">");
78 result
.append("<!ENTITY nbsp \" \">");
79 result
.append("<!ENTITY ensp \" \">");
80 result
.append("<!ENTITY emsp \" \">");
81 result
.append("<!ENTITY ndash \"–\">");
82 result
.append("<!ENTITY mdash \"—\">");
84 return result
.toString();
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" });
115 private static class MarkupHandler
extends DefaultHandler
{
118 public void startElement(String uri
, String localName
, String name
, Attributes attributes
) {
119 checkSupportedElements(name
, attributes
);
120 checkSupportedAttributes(name
, attributes
);
121 checkMandatoryAttributes(name
, attributes
);
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
);
130 private static void checkSupportedAttributes(String elementName
, Attributes attributes
) {
131 if (attributes
.getLength() > 0) {
132 List
<String
> supportedAttributes
= Arrays
.asList(SUPPORTED_ELEMENTS
.get(elementName
));
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
);
142 attributeName
= attributes
.getQName(index
);
147 private static void checkMandatoryAttributes(String elementName
, Attributes attributes
) {
148 checkIntAttribute(elementName
, attributes
, "img", "width");
149 checkIntAttribute(elementName
, attributes
, "img", "height");
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
);
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
);