1 package org
.argeo
.cms
.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
.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
;
19 /** Copy of RAP v2.3 since it is in an internal package. */
20 class MarkupValidatorCopy
{
22 // Used by Eclipse Scout project
23 public static final String MARKUP_VALIDATION_DISABLED
24 = "org.eclipse.rap.rwt.markupValidationDisabled";
26 private static final String DTD
= createDTD();
27 private static final Map
<String
, String
[]> SUPPORTED_ELEMENTS
= createSupportedElementsMap();
28 private final SAXParser saxParser
;
30 public static MarkupValidatorCopy
getInstance() {
31 return SingletonUtil
.getSessionInstance( MarkupValidatorCopy
.class );
34 public MarkupValidatorCopy() {
35 saxParser
= createSAXParser();
38 public void validate( String text
) {
39 StringBuilder markup
= new StringBuilder();
41 markup
.append( "<html>" );
42 markup
.append( text
);
43 markup
.append( "</html>" );
44 InputSource inputSource
= new InputSource( new StringReader( markup
.toString() ) );
46 saxParser
.parse( inputSource
, new MarkupHandler() );
47 } catch( RuntimeException exception
) {
49 } catch( Exception exception
) {
50 throw new IllegalArgumentException( "Failed to parse markup text", exception
);
54 public static boolean isValidationDisabledFor( Widget widget
) {
55 return Boolean
.TRUE
.equals( widget
.getData( MARKUP_VALIDATION_DISABLED
) );
58 private static SAXParser
createSAXParser() {
59 SAXParser result
= null;
60 SAXParserFactory parserFactory
= SAXParserFactory
.newInstance();
62 result
= parserFactory
.newSAXParser();
63 } catch( Exception exception
) {
64 throw new RuntimeException( "Failed to create SAX parser", exception
);
69 private static String
createDTD() {
70 StringBuilder result
= new StringBuilder();
71 result
.append( "<!DOCTYPE html [" );
72 result
.append( "<!ENTITY quot \""\">" );
73 result
.append( "<!ENTITY amp \"&\">" );
74 result
.append( "<!ENTITY apos \"'\">" );
75 result
.append( "<!ENTITY lt \"<\">" );
76 result
.append( "<!ENTITY gt \">\">" );
77 result
.append( "<!ENTITY nbsp \" \">" );
78 result
.append( "<!ENTITY ensp \" \">" );
79 result
.append( "<!ENTITY emsp \" \">" );
80 result
.append( "<!ENTITY ndash \"–\">" );
81 result
.append( "<!ENTITY mdash \"—\">" );
82 result
.append( "]>" );
83 return result
.toString();
86 private static Map
<String
, String
[]> createSupportedElementsMap() {
87 Map
<String
, String
[]> result
= new HashMap
<String
, String
[]>();
88 result
.put( "html", new String
[ 0 ] );
89 result
.put( "br", new String
[ 0 ] );
90 result
.put( "b", new String
[] { "style" } );
91 result
.put( "strong", new String
[] { "style" } );
92 result
.put( "i", new String
[] { "style" } );
93 result
.put( "em", new String
[] { "style" } );
94 result
.put( "sub", new String
[] { "style" } );
95 result
.put( "sup", new String
[] { "style" } );
96 result
.put( "big", new String
[] { "style" } );
97 result
.put( "small", new String
[] { "style" } );
98 result
.put( "del", new String
[] { "style" } );
99 result
.put( "ins", new String
[] { "style" } );
100 result
.put( "code", new String
[] { "style" } );
101 result
.put( "samp", new String
[] { "style" } );
102 result
.put( "kbd", new String
[] { "style" } );
103 result
.put( "var", new String
[] { "style" } );
104 result
.put( "cite", new String
[] { "style" } );
105 result
.put( "dfn", new String
[] { "style" } );
106 result
.put( "q", new String
[] { "style" } );
107 result
.put( "abbr", new String
[] { "style", "title" } );
108 result
.put( "span", new String
[] { "style" } );
109 result
.put( "img", new String
[] { "style", "src", "width", "height", "title", "alt" } );
110 result
.put( "a", new String
[] { "style", "href", "target", "title" } );
114 private static class MarkupHandler
extends DefaultHandler
{
117 public void startElement( String uri
, String localName
, String name
, Attributes attributes
) {
118 checkSupportedElements( name
, attributes
);
119 checkSupportedAttributes( name
, attributes
);
120 checkMandatoryAttributes( name
, attributes
);
123 private static void checkSupportedElements( String elementName
, Attributes attributes
) {
124 if( !SUPPORTED_ELEMENTS
.containsKey( elementName
) ) {
125 throw new IllegalArgumentException( "Unsupported element in markup text: " + elementName
);
129 private static void checkSupportedAttributes( String elementName
, Attributes attributes
) {
130 if( attributes
.getLength() > 0 ) {
131 List
<String
> supportedAttributes
= Arrays
.asList( SUPPORTED_ELEMENTS
.get( elementName
) );
133 String attributeName
= attributes
.getQName( index
);
134 while( attributeName
!= null ) {
135 if( !supportedAttributes
.contains( attributeName
) ) {
136 String message
= "Unsupported attribute \"{0}\" for element \"{1}\" in markup text";
137 message
= MessageFormat
.format( message
, new Object
[] { attributeName
, elementName
} );
138 throw new IllegalArgumentException( message
);
141 attributeName
= attributes
.getQName( index
);
146 private static void checkMandatoryAttributes( String elementName
, Attributes attributes
) {
147 checkIntAttribute( elementName
, attributes
, "img", "width" );
148 checkIntAttribute( elementName
, attributes
, "img", "height" );
151 private static void checkIntAttribute( String elementName
,
152 Attributes attributes
,
153 String checkedElementName
,
154 String checkedAttributeName
)
156 if( checkedElementName
.equals( elementName
) ) {
157 String attribute
= attributes
.getValue( checkedAttributeName
);
159 Integer
.parseInt( attribute
);
160 } catch( NumberFormatException exception
) {
162 = "Mandatory attribute \"{0}\" for element \"{1}\" is missing or not a valid integer";
163 Object
[] arguments
= new Object
[] { checkedAttributeName
, checkedElementName
};
164 message
= MessageFormat
.format( message
, arguments
);
165 throw new IllegalArgumentException( message
);