Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Marmalyukov2015-12-16 14:14:19 +0000
committerVictor Rubezhny2016-03-05 02:25:58 +0000
commit5497b3a7e599091d1e9a78605cb43ddf5aedae7b (patch)
tree10a0fa5201f7ae6d8f00461eec5dee2bda517f8b
parent0ebaf5532473572bc45e448280baec4cf18b63cf (diff)
downloadwebtools.sourceediting-5497b3a7e599091d1e9a78605cb43ddf5aedae7b.tar.gz
webtools.sourceediting-5497b3a7e599091d1e9a78605cb43ddf5aedae7b.tar.xz
webtools.sourceediting-5497b3a7e599091d1e9a78605cb43ddf5aedae7b.zip
[443097]Ignore undefined HTML attributes, elements validation with extension point
Change-Id: Ie25514a2c27e599dab0bbc3083daadc19d7d3e35 Signed-off-by: Konstantin Marmalyukov <kmarmaliykov@exadel.com> Signed-off-by: Victor Rubezhny <vrubezhny@exadel.com>
-rw-r--r--bundles/org.eclipse.jst.jsp.core/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.jst.jsp.ui/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.jst.jsp.ui/pom.xml2
-rw-r--r--bundles/org.eclipse.wst.css.ui/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.wst.html.core/.classpath2
-rw-r--r--bundles/org.eclipse.wst.html.core/.settings/org.eclipse.jdt.core.prefs13
-rw-r--r--bundles/org.eclipse.wst.html.core/META-INF/MANIFEST.MF7
-rw-r--r--bundles/org.eclipse.wst.html.core/plugin.properties4
-rw-r--r--bundles/org.eclipse.wst.html.core/plugin.xml2
-rw-r--r--bundles/org.eclipse.wst.html.core/pom.xml2
-rw-r--r--bundles/org.eclipse.wst.html.core/schema/customAttributeValidator.exsd136
-rw-r--r--bundles/org.eclipse.wst.html.core/schema/customTagValidator.exsd134
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLAttributeValidatorExtensionLoader.java41
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLTagValidatorExtensionLoader.java41
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/FMUtil.java4
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/HTMLAttributeValidator.java409
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java55
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/CustomValidatorUtil.java53
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomAttributeValidator.java42
-rw-r--r--bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomTagValidator.java41
-rw-r--r--bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF2
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/plugin.xml10
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator.java47
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator2.java39
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedTagValidator.java64
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/TestHTMLValidator.java45
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/customTags.html14
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/invalidAttrTestFile.html9
-rw-r--r--tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/validCustomTags.html13
29 files changed, 1039 insertions, 200 deletions
diff --git a/bundles/org.eclipse.jst.jsp.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.jst.jsp.core/META-INF/MANIFEST.MF
index e179847600..f62777c25a 100644
--- a/bundles/org.eclipse.jst.jsp.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jst.jsp.core/META-INF/MANIFEST.MF
@@ -54,7 +54,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.12.0,4.0.0)",
org.eclipse.wst.sse.core;bundle-version="[1.1.900,1.2.0)",
org.eclipse.wst.xml.core;bundle-version="[1.1.1000,1.2.0)",
org.eclipse.wst.css.core;bundle-version="[1.1.800,1.2.0)",
- org.eclipse.wst.html.core;bundle-version="[1.1.800,1.2.0)",
+ org.eclipse.wst.html.core;bundle-version="[1.1.800,1.3.0)",
org.eclipse.wst.validation;bundle-version="[1.2.700,1.3.0)",
org.eclipse.core.filesystem;bundle-version="1.6.0",
org.eclipse.osgi.services;bundle-version="3.5.0",
diff --git a/bundles/org.eclipse.jst.jsp.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.jst.jsp.ui/META-INF/MANIFEST.MF
index 6265dbad9a..5b11c31ea6 100644
--- a/bundles/org.eclipse.jst.jsp.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jst.jsp.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jst.jsp.ui; singleton:=true
-Bundle-Version: 1.1.1000.qualifier
+Bundle-Version: 1.1.1010.qualifier
Bundle-Activator: org.eclipse.jst.jsp.ui.internal.JSPUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -47,7 +47,7 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)",
org.eclipse.wst.css.ui;bundle-version="[1.0.500,1.1.0)",
org.eclipse.wst.xml.ui;bundle-version="[1.1.100,1.2.0)",
org.eclipse.jst.jsp.core;bundle-version="[1.2.401,1.3.0)",
- org.eclipse.wst.html.core;bundle-version="[1.1.400,1.2.0)",
+ org.eclipse.wst.html.core;bundle-version="[1.1.400,1.3.0)",
org.eclipse.wst.css.core;bundle-version="[1.1.300,1.2.0)",
org.eclipse.wst.xml.core;bundle-version="[1.1.500,1.2.0)",
org.eclipse.wst.sse.core;bundle-version="[1.1.500,1.2.0)",
diff --git a/bundles/org.eclipse.jst.jsp.ui/pom.xml b/bundles/org.eclipse.jst.jsp.ui/pom.xml
index d8ef8c11bd..249b9c6974 100644
--- a/bundles/org.eclipse.jst.jsp.ui/pom.xml
+++ b/bundles/org.eclipse.jst.jsp.ui/pom.xml
@@ -21,6 +21,6 @@
<groupId>org.eclipse.webtools.sourceediting</groupId>
<artifactId>org.eclipse.jst.jsp.ui</artifactId>
- <version>1.1.1000-SNAPSHOT</version>
+ <version>1.1.1010-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.wst.css.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.css.ui/META-INF/MANIFEST.MF
index f460646c5d..1f3aa08623 100644
--- a/bundles/org.eclipse.wst.css.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.css.ui/META-INF/MANIFEST.MF
@@ -41,7 +41,7 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.12.0,4.0.0)",
org.eclipse.wst.sse.ui;bundle-version="[1.3.500,1.4.0)",
org.eclipse.wst.css.core;bundle-version="[1.1.800,1.2.0)",
org.eclipse.wst.sse.core;bundle-version="[1.1.900,1.2.0)",
- org.eclipse.wst.html.core;bundle-version="[1.1.800,1.2.0)",
+ org.eclipse.wst.html.core;bundle-version="[1.1.800,1.3.0)",
org.eclipse.wst.xml.core;bundle-version="[1.1.1000,1.2.0)",
org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
org.eclipse.core.runtime;bundle-version="[3.12.0,4.0.0)",
diff --git a/bundles/org.eclipse.wst.html.core/.classpath b/bundles/org.eclipse.wst.html.core/.classpath
index 2c6f8c1f34..e84b6cc469 100644
--- a/bundles/org.eclipse.wst.html.core/.classpath
+++ b/bundles/org.eclipse.wst.html.core/.classpath
@@ -7,6 +7,6 @@
<accessrule kind="accessible" pattern="org/eclipse/wst/**"/>
</accessrules>
</classpathentry>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/bundles/org.eclipse.wst.html.core/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.wst.html.core/.settings/org.eclipse.jdt.core.prefs
index 0667e35a52..3990c17f1c 100644
--- a/bundles/org.eclipse.wst.html.core/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.wst.html.core/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,3 @@
-#Wed Mar 28 03:23:07 EDT 2007
eclipse.preferences.version=1
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
org.eclipse.jdt.core.builder.duplicateResourceTask=warning
@@ -7,24 +6,24 @@ org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
org.eclipse.jdt.core.circularClasspath=error
org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.deprecation=ignore
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
@@ -74,6 +73,6 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=di
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.wst.html.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.html.core/META-INF/MANIFEST.MF
index d422f231d9..09017dd48f 100644
--- a/bundles/org.eclipse.wst.html.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.html.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.wst.html.core; singleton:=true
-Bundle-Version: 1.1.802.qualifier
+Bundle-Version: 1.2.0.qualifier
Bundle-Activator: org.eclipse.wst.html.core.internal.HTMLCorePlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -27,7 +27,8 @@ Export-Package: org.eclipse.wst.html.core.internal;x-internal:=true,
org.eclipse.wst.html.core.internal.text;x-internal:=true,
org.eclipse.wst.html.core.internal.validate;x-internal:=true,
org.eclipse.wst.html.core.internal.validation;x-internal:=true,
- org.eclipse.wst.html.core.text
+ org.eclipse.wst.html.core.text,
+ org.eclipse.wst.html.core.validate.extension
Import-Package: com.ibm.icu.util; version="3.8"
Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
@@ -39,4 +40,4 @@ Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
org.eclipse.wst.common.modulecore;bundle-version="[1.2.0,2.0.0)";resolution:=optional,
org.eclipse.wst.validation;bundle-version="[1.2.100,1.3.0)"
Bundle-ActivationPolicy: lazy;exclude:="org.eclipse.wst.html.core.internal.contenttype,org.eclipse.wst.html.core.internal.provisional.contenttype"
-Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/bundles/org.eclipse.wst.html.core/plugin.properties b/bundles/org.eclipse.wst.html.core/plugin.properties
index 02144aae5d..602719c441 100644
--- a/bundles/org.eclipse.wst.html.core/plugin.properties
+++ b/bundles/org.eclipse.wst.html.core/plugin.properties
@@ -14,4 +14,6 @@ Structured_HTML_Document_Factory_Extension.name=Structured HTML Document Factory
HTML_Content_Type_Extension_Element.name=HTML
_taskMarker.name=HTML Task
_validationMarker.name=HTML Problem
-HTML_Syntax_Validator.name=HTML Syntax Validator \ No newline at end of file
+HTML_Syntax_Validator.name=HTML Syntax Validator
+CustomHtmlTagValidator.name=External Validator For Custom HTML Tags
+CustomHtmlAttributeValidator.name=External Validator For Custom HTML Attributes
diff --git a/bundles/org.eclipse.wst.html.core/plugin.xml b/bundles/org.eclipse.wst.html.core/plugin.xml
index d554b56d92..df9e8d268c 100644
--- a/bundles/org.eclipse.wst.html.core/plugin.xml
+++ b/bundles/org.eclipse.wst.html.core/plugin.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin>
+ <extension-point id="customTagValidator" name="%CustomHtmlTagValidator.name" schema="schema/customTagValidator.exsd"/>
+ <extension-point id="customAttributeValidator" name="%CustomHtmlAttributeValidator.name" schema="schema/customAttributeValidator.exsd"/>
<extension point="org.eclipse.wst.sse.core.modelHandler">
<modelHandler
diff --git a/bundles/org.eclipse.wst.html.core/pom.xml b/bundles/org.eclipse.wst.html.core/pom.xml
index 3e76832e81..e60bc75b2a 100644
--- a/bundles/org.eclipse.wst.html.core/pom.xml
+++ b/bundles/org.eclipse.wst.html.core/pom.xml
@@ -21,6 +21,6 @@
<groupId>org.eclipse.webtools.sourceediting</groupId>
<artifactId>org.eclipse.wst.html.core</artifactId>
- <version>1.1.802-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.wst.html.core/schema/customAttributeValidator.exsd b/bundles/org.eclipse.wst.html.core/schema/customAttributeValidator.exsd
new file mode 100644
index 0000000000..b4a15da9f7
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.core/schema/customAttributeValidator.exsd
@@ -0,0 +1,136 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.html.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.wst.html.core" id="syntaxValidator" name="Validator"/>
+ </appInfo>
+ <documentation>
+ Extension point which allows to add external validators for HTML5-like attributes.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="validator" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="validator">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.wst.html.core.internal.validate.extension.IHTMLCustomAttributeValidator:"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ Extension point for validating custom html attributes. Only one error message will be displayed for each validated attribute.
+&lt;pre&gt;
+ &lt;extension point=&quot;org.eclipse.wst.html.core.syntaxValidator&quot;&gt;
+ &lt;validator class=&quot;org.package.YourValidator&quot;&gt;&lt;/validator&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+
+YourValidator should implement IHTMLCustomAttributeValidator
+
+&lt;pre&gt;
+public class YourValidator impements IHTMLCustomAttributeValidator{
+
+ public boolean canValidate(IDOMElement target) {
+ if (target.getLocalName().startsWith(&quot;tag&quot;)) {
+ return true;
+ }
+ return false;
+ }
+
+ public void init() {
+ //called only once while validator was loaded
+ }
+
+ public ValidationMessage validateAttribute(IDOMElement target, String attrName) {
+ String tagName = target.getLocalName();
+ if (&quot;tag&quot;.equals(tagName)) {
+ if (attrName.startsWith(&quot;attr&quot;)) {
+ Segment segment = CustomValidatorUtil.getAttributeSegment((IDOMNode)target.getAttributeNode(attrName), ATTR_REGION_NAME);
+ return new ValidationMessage(&quot;Attribute started with attr is not allowed&quot;, segment.getOffset(), segment.getLength(), ValidationMessage.ERROR);
+ }
+ }
+ return null;
+}
+}
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/bundles/org.eclipse.wst.html.core/schema/customTagValidator.exsd b/bundles/org.eclipse.wst.html.core/schema/customTagValidator.exsd
new file mode 100644
index 0000000000..303c55a79d
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.core/schema/customTagValidator.exsd
@@ -0,0 +1,134 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.html.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.wst.html.core" id="syntaxValidator" name="Validator"/>
+ </appInfo>
+ <documentation>
+ Extension point which allows to add external validators for HTML5-like tags.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="validator" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="validator">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.wst.html.core.internal.validate.extension.IHTMLCustomTagValidator:"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ Extension point for validating custom html tags. Only one error message will be displayed for each validated tag.
+&lt;pre&gt;
+ &lt;extension point=&quot;org.eclipse.wst.html.core.syntaxValidator&quot;&gt;
+ &lt;validator class=&quot;org.package.YourValidator&quot;&gt;&lt;/validator&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+
+YourValidator should implement IHTMLCustomTagValidator
+
+&lt;pre&gt;
+public class YourValidator impements IHTMLCustomTagValidator{
+
+ public boolean canValidate(IDOMElement target) {
+ if (target.getLocalName().startsWith(&quot;tag&quot;)) {
+ return true;
+ }
+ return false;
+ }
+
+ public void init() {
+ //called only once while validator was loaded
+ }
+
+ public ValidationMessage validateTag(IDOMElement target) {
+ String tagName = target.getLocalName();
+ if (tagName.contains(&quot;error&quot;)) {
+ Segment segment = CustomValidatorUtil.getTagSegment(target, SEG_START_TAG_NAME);
+ return new ValidationMessage(&quot;This is error tag&quot;, segment.getOffset(), segment.getLength(), ValidationMessage.ERROR);
+ }
+ return null;
+ }
+}
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLAttributeValidatorExtensionLoader.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLAttributeValidatorExtensionLoader.java
new file mode 100644
index 0000000000..e900ee4a1e
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLAttributeValidatorExtensionLoader.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.core.internal.validate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+
+public class CustomHTMLAttributeValidatorExtensionLoader {
+private List<IConfigurationElement> validators;
+
+ public List<IConfigurationElement> getValidators() {
+ return validators;
+ }
+
+ private CustomHTMLAttributeValidatorExtensionLoader() {
+ validators = new ArrayList<IConfigurationElement>();
+ IConfigurationElement[] configurationElements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.wst.html.core.customAttributeValidator");
+ for (IConfigurationElement e : configurationElements) {
+ validators.add(e);
+ }
+ }
+
+ private static class UnknownValidatorExtensionLoaderHolder {
+ public static final CustomHTMLAttributeValidatorExtensionLoader instance = new CustomHTMLAttributeValidatorExtensionLoader();
+ }
+
+ public static CustomHTMLAttributeValidatorExtensionLoader getInstance() {
+ return UnknownValidatorExtensionLoaderHolder.instance;
+ }
+}
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLTagValidatorExtensionLoader.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLTagValidatorExtensionLoader.java
new file mode 100644
index 0000000000..6c6c4301fd
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/CustomHTMLTagValidatorExtensionLoader.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.core.internal.validate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+
+public class CustomHTMLTagValidatorExtensionLoader {
+ private List<IConfigurationElement> validators;
+
+ public List<IConfigurationElement> getValidators() {
+ return validators;
+ }
+
+ private CustomHTMLTagValidatorExtensionLoader() {
+ validators = new ArrayList<IConfigurationElement>();
+ IConfigurationElement[] configurationElements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.wst.html.core.customTagValidator");
+ for (IConfigurationElement e : configurationElements) {
+ validators.add(e);
+ }
+ }
+
+ private static class UnknownValidatorExtensionLoaderHolder {
+ public static final CustomHTMLTagValidatorExtensionLoader instance = new CustomHTMLTagValidatorExtensionLoader();
+ }
+
+ public static CustomHTMLTagValidatorExtensionLoader getInstance() {
+ return UnknownValidatorExtensionLoaderHolder.instance;
+ }
+}
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/FMUtil.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/FMUtil.java
index f3ee02a826..433c4bb223 100644
--- a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/FMUtil.java
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/FMUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -19,7 +19,7 @@ import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
-final class FMUtil {
+public final class FMUtil {
public final static int SEG_NONE = 0;
public final static int SEG_WHOLE_TAG = 1;
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/HTMLAttributeValidator.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/HTMLAttributeValidator.java
index 1e200cc208..d58e883285 100644
--- a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/HTMLAttributeValidator.java
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/HTMLAttributeValidator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2014 IBM Corporation and others.
+ * Copyright (c) 2004, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,9 +7,11 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Red Hat, Inc. - external validator extension
*******************************************************************************/
package org.eclipse.wst.html.core.internal.validate;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -23,7 +25,9 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
@@ -32,14 +36,18 @@ import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.wst.html.core.internal.HTMLCorePlugin;
+import org.eclipse.wst.html.core.internal.Logger;
import org.eclipse.wst.html.core.internal.document.HTMLDocumentTypeConstants;
import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames;
+import org.eclipse.wst.html.core.validate.extension.IHTMLCustomAttributeValidator;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
@@ -58,8 +66,8 @@ import org.w3c.dom.NamedNodeMap;
public class HTMLAttributeValidator extends PrimeValidator {
private static final String JAVASCRIPT_PREFIX = "javascript:"; //$NON-NLS-1$
- private static final int REGION_NAME = 1;
- private static final int REGION_VALUE = 2;
+ public static final int REGION_NAME = 1;
+ public static final int REGION_VALUE = 2;
// <<D210422
private static final char SINGLE_QUOTE = '\'';
private static final char DOUBLE_QUOTE = '\"';
@@ -81,6 +89,7 @@ public class HTMLAttributeValidator extends PrimeValidator {
private static final String ATTR_NAME_WAI_ARIA = "aria-"; //$NON-NLS-1$
private static final int ATTR_NAME_WAI_ARIA_LENGTH = ATTR_NAME_WAI_ARIA.length();
+ private List<IHTMLCustomAttributeValidator> externalValidators;
/**
* HTMLAttributeValidator constructor comment.
@@ -92,7 +101,7 @@ public class HTMLAttributeValidator extends PrimeValidator {
/**
*/
- private Segment getErrorSegment(IDOMNode errorNode, int regionType) {
+ public static Segment getErrorSegment(IDOMNode errorNode, int regionType) {
ITextRegion rgn = null;
switch (regionType) {
case REGION_NAME :
@@ -137,212 +146,266 @@ public class HTMLAttributeValidator extends PrimeValidator {
if (CMUtil.isForeign(target))
return;
CMElementDeclaration edec = CMUtil.getDeclaration(target);
- if (edec == null)
- return;
- CMNamedNodeMap declarations = edec.getAttributes();
-
- List modelQueryNodes = null;
- NamedNodeMap attrs = target.getAttributes();
- for (int i = 0; i < attrs.getLength(); i++) {
- int rgnType = REGION_NAME;
- int state = ErrorState.NONE_ERROR;
- Attr a = (Attr) attrs.item(i);
- // D203637; If the target attr has prefix, the validator should
- // not
- // warn about it. That is, just ignore. It is able to check
- // whether
- // an attr has prefix or not by calling XMLAttr#isGlobalAttr().
- // When a attr has prefix (not global), it returns false.
- boolean isXMLAttr = a instanceof IDOMAttr;
- if (isXMLAttr) {
- IDOMAttr xmlattr = (IDOMAttr) a;
- if (!xmlattr.isGlobalAttr() || xmlattr.getNameRegion() instanceof ITextRegionContainer)
- continue; // skip futher validation and begin next loop.
- }
-
- CMAttributeDeclaration adec = (CMAttributeDeclaration) declarations.getNamedItem(a.getName());
- final String attrName = a.getName().toLowerCase(Locale.US);
- /* Check the modelquery if nothing is declared by the element declaration */
- if (adec == null) {
- if (modelQueryNodes == null)
- modelQueryNodes = ModelQueryUtil.getModelQuery(target.getOwnerDocument()).getAvailableContent((Element) node, edec, ModelQuery.INCLUDE_ATTRIBUTES);
-
-
- for (int k = 0; k < modelQueryNodes.size(); k++) {
- CMNode cmnode = (CMNode) modelQueryNodes.get(k);
- if (cmnode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION && cmnode.getNodeName().toLowerCase(Locale.US).equals(attrName)) {
- adec = (CMAttributeDeclaration) cmnode;
- break;
- }
+ if (edec == null) {
+ NamedNodeMap attrs = target.getAttributes();
+ // unknown tag - go to validators from extension point
+ for (int i = 0; i < attrs.getLength(); i++) {
+ Attr a = (Attr) attrs.item(i);
+ final String attrName = a.getName().toLowerCase(Locale.US);
+ // Check for user-defined exclusions
+ if (shouldValidateAttributeName(target, attrName)) {
+ validateWithExtension(target, a, attrName);
}
}
-
- if (adec == null) {
- if ((attrName.startsWith(ATTR_NAME_DATA) && attrName.length() > ATTR_NAME_DATA_LENGTH) ||
- (attrName.startsWith(ATTR_NAME_USER_AGENT_FEATURE) && attrName.length() > ATTR_NAME_USER_AGENT_FEATURE_LENGTH) ||
- (attrName.startsWith(ATTR_NAME_WAI_ARIA) && attrName.length() > ATTR_NAME_WAI_ARIA_LENGTH)) {
- if (isHTML5(target))
- continue;
- }
- // Check for user-defined exclusions
- if (!shouldValidateAttributeName(target, attrName))
- continue;
-
- // No attr declaration was found. That is, the attr name is
- // undefined.
- // but not regard it as undefined name if it includes nested
- // region
- if (!hasNestedRegion(((IDOMNode) a).getNameRegion())) {
- rgnType = REGION_NAME;
- state = ErrorState.UNDEFINED_NAME_ERROR;
+ } else {
+ CMNamedNodeMap declarations = edec.getAttributes();
+
+ List modelQueryNodes = null;
+ NamedNodeMap attrs = target.getAttributes();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ int rgnType = REGION_NAME;
+ int state = ErrorState.NONE_ERROR;
+ Attr a = (Attr) attrs.item(i);
+ // D203637; If the target attr has prefix, the validator should
+ // not
+ // warn about it. That is, just ignore. It is able to check
+ // whether
+ // an attr has prefix or not by calling XMLAttr#isGlobalAttr().
+ // When a attr has prefix (not global), it returns false.
+ boolean isXMLAttr = a instanceof IDOMAttr;
+ if (isXMLAttr) {
+ IDOMAttr xmlattr = (IDOMAttr) a;
+ if (!xmlattr.isGlobalAttr() || xmlattr.getNameRegion() instanceof ITextRegionContainer)
+ continue; // skip futher validation and begin next loop.
}
- } else {
- // The attr declaration was found.
- // At 1st, the name should be checked.
- if (CMUtil.isObsolete(adec)){
- state = ErrorState.OBSOLETE_ATTR_NAME_ERROR;
+
+ CMAttributeDeclaration adec = (CMAttributeDeclaration) declarations.getNamedItem(a.getName());
+ final String attrName = a.getName().toLowerCase(Locale.US);
+ /* Check the modelquery if nothing is declared by the element declaration */
+ if (adec == null) {
+ if (modelQueryNodes == null)
+ modelQueryNodes = ModelQueryUtil.getModelQuery(target.getOwnerDocument()).getAvailableContent((Element) node, edec, ModelQuery.INCLUDE_ATTRIBUTES);
+
+
+ for (int k = 0; k < modelQueryNodes.size(); k++) {
+ CMNode cmnode = (CMNode) modelQueryNodes.get(k);
+ if (cmnode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION && cmnode.getNodeName().toLowerCase(Locale.US).equals(attrName)) {
+ adec = (CMAttributeDeclaration) cmnode;
+ break;
+ }
+ }
}
- if (CMUtil.isHTML(edec) && (!CMUtil.isXHTML(edec))) {
- // If the target element is pure HTML (not XHTML), some
- // attributes
- // might be written in boolean format. It should be check
- // specifically.
- if (CMUtil.isBooleanAttr(adec) && ((IDOMAttr) a).hasNameOnly())
- continue; // OK, keep going. No more check is needed
- // against this attr.
+
+ if (adec == null) {
+ if ((attrName.startsWith(ATTR_NAME_DATA) && attrName.length() > ATTR_NAME_DATA_LENGTH) ||
+ (attrName.startsWith(ATTR_NAME_USER_AGENT_FEATURE) && attrName.length() > ATTR_NAME_USER_AGENT_FEATURE_LENGTH) ||
+ (attrName.startsWith(ATTR_NAME_WAI_ARIA) && attrName.length() > ATTR_NAME_WAI_ARIA_LENGTH)) {
+ if (isHTML5(target))
+ continue;
+ }
+ // Check for user-defined exclusions
+ if (!shouldValidateAttributeName(target, attrName))
+ continue;
+
+ // No attr declaration was found. That is, the attr name is
+ // undefined.
+ // but not regard it as undefined name if it includes nested
+ // region
+
+ // Then look into extension point for external validator
+ validateWithExtension(target, a, attrName);
} else {
- // If the target is other than pure HTML (JSP or XHTML),
- // the name
- // must be checked exactly (ie in case sensitive way).
- String actual = a.getName();
- String desired = adec.getAttrName();
- if (!actual.equals(desired)) { // case mismatch
- rgnType = REGION_NAME;
- state = ErrorState.MISMATCHED_ERROR;
+ // The attr declaration was found.
+ // At 1st, the name should be checked.
+ if (CMUtil.isObsolete(adec)){
+ state = ErrorState.OBSOLETE_ATTR_NAME_ERROR;
}
- }
- // Then, the value must be checked.
- if (state == ErrorState.NONE_ERROR) { // Need more check.
- // Now, the value should be checked, if the type is ENUM.
- CMDataType attrType = adec.getAttrType();
- if (a instanceof IDOMAttr) {
- final ITextRegion region = ((IDOMAttr) a).getEqualRegion();
- if (region == null) {
+ if (CMUtil.isHTML(edec) && (!CMUtil.isXHTML(edec))) {
+ // If the target element is pure HTML (not XHTML), some
+ // attributes
+ // might be written in boolean format. It should be check
+ // specifically.
+ if (CMUtil.isBooleanAttr(adec) && ((IDOMAttr) a).hasNameOnly())
+ continue; // OK, keep going. No more check is needed
+ // against this attr.
+ } else {
+ // If the target is other than pure HTML (JSP or XHTML),
+ // the name
+ // must be checked exactly (ie in case sensitive way).
+ String actual = a.getName();
+ String desired = adec.getAttrName();
+ if (!actual.equals(desired)) { // case mismatch
rgnType = REGION_NAME;
- state = ErrorState.MISSING_ATTR_VALUE_EQUALS_ERROR;
+ state = ErrorState.MISMATCHED_ERROR;
}
}
- String actualValue = a.getValue();
- if (attrType.getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED) {
- // Check FIXED value.
- String validValue = attrType.getImpliedValue();
- if (!actualValue.equals(validValue)) {
- rgnType = REGION_VALUE;
- state = ErrorState.UNDEFINED_VALUE_ERROR;
+ // Then, the value must be checked.
+ if (state == ErrorState.NONE_ERROR) { // Need more check.
+ // Now, the value should be checked, if the type is ENUM.
+ CMDataType attrType = adec.getAttrType();
+ if (a instanceof IDOMAttr) {
+ final ITextRegion region = ((IDOMAttr) a).getEqualRegion();
+ if (region == null) {
+ rgnType = REGION_NAME;
+ state = ErrorState.MISSING_ATTR_VALUE_EQUALS_ERROR;
+ }
}
- }
- else if (CMDataType.URI.equals(attrType.getDataTypeName())) {
- if (actualValue.indexOf('#') < 0 && actualValue.indexOf(":/") < 0 && !actualValue.toLowerCase(Locale.ENGLISH).startsWith(JAVASCRIPT_PREFIX) && CMUtil.isHTML(edec)) { //$NON-NLS-1$ //$NON-NLS-2$
- IStructuredDocumentRegion start = ((IDOMNode) node).getStartStructuredDocumentRegion();
- // roundabout start tag check
- if (start != null && start.getFirstRegion().getTextLength() == 1) {
- // only check when we have a way to set dependencies
- Collection dependencies = (Collection) ((IDOMNode) ((IDOMNode) node).getOwnerDocument()).getUserData(HTMLValidationAdapterFactory.DEPENDENCIES);
- if (dependencies != null) {
- IPath basePath = new Path(((IDOMNode) node).getModel().getBaseLocation());
- if (basePath.segmentCount() > 1) {
- IPath path = ModuleCoreSupport.resolve(basePath, actualValue);
- IResource found = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
- if (found != null) {
- dependencies.add(found);
- }
- }
- }
+ String actualValue = a.getValue();
+ if (attrType.getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED) {
+ // Check FIXED value.
+ String validValue = attrType.getImpliedValue();
+ if (!actualValue.equals(validValue)) {
+ rgnType = REGION_VALUE;
+ state = ErrorState.UNDEFINED_VALUE_ERROR;
}
}
- }
- else if (CMDataType.ENUM.equals(attrType.getDataTypeName())) {
- /*
- * Check current value is valid among a known list.
- * There may be enumerated values provided even when
- * the datatype is not ENUM, but we'll only validate
- * against that list if the type matches.
- */
- String[] enumeratedValues = attrType.getEnumeratedValues();
- // several candidates are found.
- boolean found = false;
- for (int j = 0; j < enumeratedValues.length; j++) {
- // At 1st, compare ignoring case.
- if (actualValue.equalsIgnoreCase(enumeratedValues[j])) {
- found = true;
- if (CMUtil.isCaseSensitive(edec) && (!actualValue.equals(enumeratedValues[j]))) {
- rgnType = REGION_VALUE;
- state = ErrorState.MISMATCHED_VALUE_ERROR;
+ else if (CMDataType.URI.equals(attrType.getDataTypeName())) {
+ if (actualValue.indexOf('#') < 0 && actualValue.indexOf(":/") < 0 && !actualValue.toLowerCase(Locale.ENGLISH).startsWith(JAVASCRIPT_PREFIX) && CMUtil.isHTML(edec)) { //$NON-NLS-1$ //$NON-NLS-2$
+ IStructuredDocumentRegion start = ((IDOMNode) node).getStartStructuredDocumentRegion();
+ // roundabout start tag check
+ if (start != null && start.getFirstRegion().getTextLength() == 1) {
+ // only check when we have a way to set dependencies
+ Collection dependencies = (Collection) ((IDOMNode) ((IDOMNode) node).getOwnerDocument()).getUserData(HTMLValidationAdapterFactory.DEPENDENCIES);
+ if (dependencies != null) {
+ IPath basePath = new Path(((IDOMNode) node).getModel().getBaseLocation());
+ if (basePath.segmentCount() > 1) {
+ IPath path = ModuleCoreSupport.resolve(basePath, actualValue);
+ IResource found = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
+ if (found != null) {
+ dependencies.add(found);
+ }
+ }
+ }
}
- break; // exit the loop.
}
}
- if (!found) {
- // retrieve and check extended values (retrieval can call extensions, which may take longer)
- String[] modelQueryExtensionValues = ModelQueryUtil.getModelQuery(target.getOwnerDocument()).getPossibleDataTypeValues((Element) node, adec);
- // copied loop from above
- for (int j = 0; j < modelQueryExtensionValues.length; j++) {
+ else if (CMDataType.ENUM.equals(attrType.getDataTypeName())) {
+ /*
+ * Check current value is valid among a known list.
+ * There may be enumerated values provided even when
+ * the datatype is not ENUM, but we'll only validate
+ * against that list if the type matches.
+ */
+ String[] enumeratedValues = attrType.getEnumeratedValues();
+ // several candidates are found.
+ boolean found = false;
+ for (int j = 0; j < enumeratedValues.length; j++) {
// At 1st, compare ignoring case.
- if (actualValue.equalsIgnoreCase(modelQueryExtensionValues[j])) {
+ if (actualValue.equalsIgnoreCase(enumeratedValues[j])) {
found = true;
- if (CMUtil.isCaseSensitive(edec) && (!actualValue.equals(modelQueryExtensionValues[j]))) {
+ if (CMUtil.isCaseSensitive(edec) && (!actualValue.equals(enumeratedValues[j]))) {
rgnType = REGION_VALUE;
state = ErrorState.MISMATCHED_VALUE_ERROR;
}
break; // exit the loop.
}
}
- // No candidate was found. That is,
- // actualValue is invalid.
- // but not regard it as undefined value if it
- // includes nested region.
- if (!hasNestedRegion(((IDOMNode) a).getValueRegion())) {
- rgnType = REGION_VALUE;
- state = ErrorState.UNDEFINED_VALUE_ERROR;
+ if (!found) {
+ // retrieve and check extended values (retrieval can call extensions, which may take longer)
+ String[] modelQueryExtensionValues = ModelQueryUtil.getModelQuery(target.getOwnerDocument()).getPossibleDataTypeValues((Element) node, adec);
+ // copied loop from above
+ for (int j = 0; j < modelQueryExtensionValues.length; j++) {
+ // At 1st, compare ignoring case.
+ if (actualValue.equalsIgnoreCase(modelQueryExtensionValues[j])) {
+ found = true;
+ if (CMUtil.isCaseSensitive(edec) && (!actualValue.equals(modelQueryExtensionValues[j]))) {
+ rgnType = REGION_VALUE;
+ state = ErrorState.MISMATCHED_VALUE_ERROR;
+ }
+ break; // exit the loop.
+ }
+ }
+ // No candidate was found. That is,
+ // actualValue is invalid.
+ // but not regard it as undefined value if it
+ // includes nested region.
+ if (!hasNestedRegion(((IDOMNode) a).getValueRegion())) {
+ rgnType = REGION_VALUE;
+ state = ErrorState.UNDEFINED_VALUE_ERROR;
+ }
}
}
}
- }
- // <<D210422
- if (state == ErrorState.NONE_ERROR) { // Need more check.
- if (isXMLAttr) {
- String source = ((IDOMAttr) a).getValueRegionText();
- if (source != null) {
- char firstChar = source.charAt(0);
- char lastChar = source.charAt(source.length() - 1);
- boolean unclosedAttr = false;
- if (isQuote(firstChar) || isQuote(lastChar)) {
- if (lastChar != firstChar) {
- unclosedAttr = true;
+ // <<D210422
+ if (state == ErrorState.NONE_ERROR) { // Need more check.
+ if (isXMLAttr) {
+ String source = ((IDOMAttr) a).getValueRegionText();
+ if (source != null) {
+ char firstChar = source.charAt(0);
+ char lastChar = source.charAt(source.length() - 1);
+ boolean unclosedAttr = false;
+ if (isQuote(firstChar) || isQuote(lastChar)) {
+ if (lastChar != firstChar) {
+ unclosedAttr = true;
+ }
}
- }
- else{
- if (CMUtil.isXHTML(edec)){
- unclosedAttr = true;
+ else{
+ if (CMUtil.isXHTML(edec)){
+ unclosedAttr = true;
+ }
+ }
+ if (unclosedAttr){
+ rgnType = REGION_VALUE;
+ state = ErrorState.UNCLOSED_ATTR_VALUE;
}
- }
- if (unclosedAttr){
- rgnType = REGION_VALUE;
- state = ErrorState.UNCLOSED_ATTR_VALUE;
}
}
}
+ // D210422
+ }
+ if (state != ErrorState.NONE_ERROR) {
+ Segment seg = getErrorSegment((IDOMNode) a, rgnType);
+ if (seg != null)
+ reporter.report(new ErrorInfoImpl(state, seg, a));
+ }
+ }
+ }
+ }
+
+ private void initValidators(IStructuredDocument doc) {
+ externalValidators = new ArrayList<IHTMLCustomAttributeValidator>();
+ for (IConfigurationElement e : CustomHTMLAttributeValidatorExtensionLoader.getInstance().getValidators()) {
+ IHTMLCustomAttributeValidator validator;
+ try {
+ validator = (IHTMLCustomAttributeValidator) e.createExecutableExtension("class");
+ validator.init(doc);
+ externalValidators.add(validator);
+ } catch (CoreException e1) {
+ Logger.logException(e1);
+ }
+ }
+ }
+
+ private void validateWithExtension(Element target, Attr a, String attrName) {
+ boolean validated = false;
+ if (externalValidators == null) {
+ initValidators(((IDOMElement)target).getStructuredDocument());
+ }
+
+ for (IHTMLCustomAttributeValidator v : externalValidators) {
+ try {
+ if (v.canValidate((IDOMElement) target, attrName)) {
+ validated = true;
+ ValidationMessage result = v.validateAttribute((IDOMElement) target, attrName);
+ if (result != null) {
+ // report only one validation result or nothing if all reports are null
+ reporter.report(result);
+ break;
+ }
}
- // D210422
+ } catch (Throwable t) {
+ Logger.logException(t);
}
- if (state != ErrorState.NONE_ERROR) {
- Segment seg = getErrorSegment((IDOMNode) a, rgnType);
+ }
+ if (!validated) {
+ if (!hasNestedRegion(((IDOMNode) a).getNameRegion())) {
+ Segment seg = getErrorSegment((IDOMNode) a, REGION_NAME);
if (seg != null)
- reporter.report(new ErrorInfoImpl(state, seg, a));
+ reporter.report(new ErrorInfoImpl(ErrorState.UNDEFINED_NAME_ERROR, seg, a));
}
}
}
-
+
/**
* True if container has nested regions, meaning container is probably too
* complicated (like JSP regions) to validate with this validator.
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java
index 7023e2c2b4..73413f4227 100644
--- a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2014 IBM Corporation and others.
+ * Copyright (c) 2004, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,36 +7,45 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Red Hat, Inc. - external validator extension
*******************************************************************************/
package org.eclipse.wst.html.core.internal.validate;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.wst.html.core.internal.HTMLCorePlugin;
+import org.eclipse.wst.html.core.internal.Logger;
import org.eclipse.wst.html.core.internal.contentmodel.HTMLElementDeclaration;
import org.eclipse.wst.html.core.internal.contentmodel.HTMLPropertyDeclaration;
import org.eclipse.wst.html.core.internal.document.HTMLDocumentTypeEntry;
import org.eclipse.wst.html.core.internal.document.HTMLDocumentTypeRegistry;
import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames;
import org.eclipse.wst.html.core.internal.provisional.HTML50Namespace;
+import org.eclipse.wst.html.core.validate.extension.IHTMLCustomTagValidator;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.internal.validate.ErrorInfo;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.document.InvalidCharacterException;
import org.eclipse.wst.xml.core.internal.document.SourceValidator;
@@ -53,7 +62,8 @@ import org.w3c.dom.Node;
class SyntaxValidator extends PrimeValidator implements ErrorState {
private IPreferencesService fPreferenceService;
private static Map fIgnorePatterns = new HashMap(); // A storage for ignore patterns (instances of StringMatcher)
-
+ private List<IHTMLCustomTagValidator> externalValidators;
+
static private boolean isValidRegion(ITextRegion rgn) {
String type = rgn.getType();
if (type == null)
@@ -324,8 +334,31 @@ class SyntaxValidator extends PrimeValidator implements ErrorState {
}
else {
if (shouldValidateElementName(info.target)) {
- Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_START_TAG_NAME);
- report(UNDEFINED_NAME_ERROR, errorSeg, info.target);
+ // not excluded in preferences - check for extension point
+ boolean validated = false;
+
+ if (externalValidators == null) {
+ initValidators(info.target.getStructuredDocument());
+ }
+ for (IHTMLCustomTagValidator v : externalValidators) {
+ try {
+ if (v.canValidate(info.target)) {
+ validated = true;
+ ValidationMessage result = v.validateTag(info.target);
+ if(result != null) {
+ // report only one validation result or nothing if all reports are null
+ reporter.report(result);
+ break;
+ }
+ }
+ } catch (Throwable t) {
+ Logger.logException(t);
+ }
+ }
+ if (!validated) {
+ Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_START_TAG_NAME);
+ report(UNDEFINED_NAME_ERROR, errorSeg, info.target);
+ }
}
}
}
@@ -339,6 +372,20 @@ class SyntaxValidator extends PrimeValidator implements ErrorState {
}
}
+ private void initValidators(IStructuredDocument doc) {
+ externalValidators = new ArrayList<IHTMLCustomTagValidator>();
+ for (IConfigurationElement e : CustomHTMLTagValidatorExtensionLoader.getInstance().getValidators()) {
+ IHTMLCustomTagValidator validator;
+ try {
+ validator = (IHTMLCustomTagValidator) e.createExecutableExtension("class");
+ validator.init(doc);
+ externalValidators.add(validator);
+ } catch (CoreException e1) {
+ Logger.logException(e1);
+ }
+ }
+ }
+
private boolean shouldValidateElementName(Element target) {
Object adapter = (target instanceof IAdaptable ? ((IAdaptable)target).getAdapter(IResource.class) : null);
IProject project = (adapter instanceof IResource ? ((IResource)adapter).getProject() : null);
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/CustomValidatorUtil.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/CustomValidatorUtil.java
new file mode 100644
index 0000000000..ce400b2679
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/CustomValidatorUtil.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.core.validate.extension;
+
+import org.eclipse.wst.html.core.internal.validate.FMUtil;
+import org.eclipse.wst.html.core.internal.validate.HTMLAttributeValidator;
+import org.eclipse.wst.html.core.internal.validate.Segment;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * @since 1.2
+ */
+public class CustomValidatorUtil {
+ public static final int ATTR_REGION_NAME = HTMLAttributeValidator.REGION_NAME;
+ public static final int ATTR_REGION_VALUE = HTMLAttributeValidator.REGION_VALUE;
+
+ public final static int TAG_SEG_NONE = FMUtil.SEG_NONE;
+ public final static int SEG_WHOLE_TAG = FMUtil.SEG_WHOLE_TAG;
+ public final static int SEG_START_TAG = FMUtil.SEG_START_TAG;
+ public final static int SEG_END_TAG = FMUtil.SEG_END_TAG;
+ public final static int SEG_START_TAG_NAME = FMUtil.SEG_START_TAG_NAME;
+ public final static int SEG_END_TAG_NAME = FMUtil.SEG_END_TAG_NAME;
+
+ /**
+ * Error segment for attribute validation
+ *
+ * @param errorNode attribute with error
+ * @param regionType type of region where error marker should be placed
+ * @return {@link Segment} which determines error marker location
+ */
+ public final static Segment getAttributeSegment(IDOMNode errorNode, int regionType) {
+ return HTMLAttributeValidator.getErrorSegment(errorNode, regionType);
+ }
+
+ /**
+ * Error segment for tag validation
+ *
+ * @param target tag with error
+ * @param segType type of segment where error marker should be placed
+ * @return {@link Segment} which determines error marker location
+ */
+ public final static Segment getTagSegment(IDOMNode target, int segType) {
+ return FMUtil.getSegment(target, segType);
+ }
+}
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomAttributeValidator.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomAttributeValidator.java
new file mode 100644
index 0000000000..ba4894bc16
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomAttributeValidator.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.core.validate.extension;
+
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @since 1.2
+ */
+public interface IHTMLCustomAttributeValidator {
+ /**
+ * Validator initialization. This method is called before validator loading.
+ *
+ * @param doc validated document
+ */
+ public void init(IStructuredDocument doc);
+
+ /**
+ *
+ * @param target tag to be validated
+ * @return <code>true</code> if validator can validate tag
+ */
+ public boolean canValidate(IDOMElement target, String attrName);
+
+ /**Validates specified attribute of specified tag
+ *
+ * @param target tag to be validated
+ * @param attrName attribute to be validated
+ * @return <code>null</code> if no error happens or {@link ValidationMessage} with error message and error region
+ */
+ public ValidationMessage validateAttribute(IDOMElement target, String attrName);
+}
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomTagValidator.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomTagValidator.java
new file mode 100644
index 0000000000..f132f4f680
--- /dev/null
+++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/extension/IHTMLCustomTagValidator.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.core.validate.extension;
+
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+
+/**
+ * @since 1.2
+ */
+public interface IHTMLCustomTagValidator {
+ /**
+ * Validator initialization. This method is called only once during validator loading.
+ *
+ * @param doc validated document
+ */
+ public void init(IStructuredDocument doc);
+
+ /**
+ *
+ * @param target tag to be validated
+ * @return <code>true</code> if validator can validate tag
+ */
+ public boolean canValidate(IDOMElement target);
+
+ /**Validate specified tag
+ *
+ * @param target tag to be validated
+ * @return <code>null</code> if no error happens or {@link ValidationMessage} with error message and error region
+ */
+ public ValidationMessage validateTag(IDOMElement target);
+}
diff --git a/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF
index ac6978c871..2cadaf3d13 100644
--- a/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF
@@ -41,7 +41,7 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.12.0,4.0.0)",
org.eclipse.wst.css.ui;bundle-version="[1.0.1000,1.1.0)",
org.eclipse.wst.sse.core;bundle-version="[1.1.900,1.2.0)",
org.eclipse.wst.css.core;bundle-version="[1.1.800,1.2.0)",
- org.eclipse.wst.html.core;bundle-version="[1.1.800,1.2.0)",
+ org.eclipse.wst.html.core;bundle-version="[1.1.800,1.3.0)",
org.eclipse.wst.xml.core;bundle-version="[1.1.1000,1.2.0)",
org.eclipse.core.resources;bundle-version="[3.11.0,4.0.0)",
org.eclipse.core.runtime;bundle-version="[3.12.0,4.0.0)",
diff --git a/tests/org.eclipse.wst.html.ui.tests/plugin.xml b/tests/org.eclipse.wst.html.ui.tests/plugin.xml
index ff9dcb36f1..016dc5121b 100644
--- a/tests/org.eclipse.wst.html.ui.tests/plugin.xml
+++ b/tests/org.eclipse.wst.html.ui.tests/plugin.xml
@@ -11,5 +11,13 @@
id="org.eclipse.wst.html.ui.tests.viewer.ViewerTestHTML">
</view>
</extension>
-
+ <extension point="org.eclipse.wst.html.core.customTagValidator">
+ <validator class="org.eclipse.wst.html.ui.tests.validation.CustomExtendedTagValidator"></validator>
+ </extension>
+ <extension point="org.eclipse.wst.html.core.customAttributeValidator">
+ <validator class="org.eclipse.wst.html.ui.tests.validation.CustomExtendedAttributeValidator"></validator>
+ </extension>
+ <extension point="org.eclipse.wst.html.core.customAttributeValidator">
+ <validator class="org.eclipse.wst.html.ui.tests.validation.CustomExtendedAttributeValidator2"></validator>
+ </extension>
</plugin>
diff --git a/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator.java b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator.java
new file mode 100644
index 0000000000..b99d857361
--- /dev/null
+++ b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.ui.tests.validation;
+
+import org.eclipse.wst.html.core.internal.validate.Segment;
+import org.eclipse.wst.html.core.validate.extension.CustomValidatorUtil;
+import org.eclipse.wst.html.core.validate.extension.IHTMLCustomAttributeValidator;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public class CustomExtendedAttributeValidator implements IHTMLCustomAttributeValidator {
+
+ public void init(IStructuredDocument doc) {
+ // do nothing
+ }
+
+ public boolean canValidate(IDOMElement target, String attrName) {
+ if (target.getLocalName().startsWith("eclipse")) {
+ return true;
+ }
+ return false;
+ }
+
+
+ public ValidationMessage validateAttribute(IDOMElement target, String attrName) {
+ if ("plugins".equals(attrName)) {
+ try {
+ String attrValue = target.getAttribute(attrName);
+ Integer.parseInt(attrValue);
+ } catch (NumberFormatException e) {
+ Segment segment = CustomValidatorUtil.getAttributeSegment((IDOMNode)target.getAttributeNode(attrName), CustomValidatorUtil.ATTR_REGION_NAME);
+ return new ValidationMessage("Attribute should be integer", segment.getOffset(), segment.getLength(), ValidationMessage.ERROR);
+ }
+ }
+ return null;
+ }
+}
diff --git a/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator2.java b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator2.java
new file mode 100644
index 0000000000..123e966a10
--- /dev/null
+++ b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedAttributeValidator2.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.ui.tests.validation;
+
+import org.eclipse.wst.html.core.internal.validate.Segment;
+import org.eclipse.wst.html.core.validate.extension.CustomValidatorUtil;
+import org.eclipse.wst.html.core.validate.extension.IHTMLCustomAttributeValidator;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public class CustomExtendedAttributeValidator2 implements IHTMLCustomAttributeValidator {
+
+ public void init(IStructuredDocument doc) {
+ // do nothing
+ }
+
+ public boolean canValidate(IDOMElement target, String attrName) {
+ return attrName.startsWith("pr-") ? true : false;
+ }
+
+ public ValidationMessage validateAttribute(IDOMElement target, String attrName) {
+ if (attrName.startsWith("pr-")) {
+ return null;
+ }
+ Segment segment = CustomValidatorUtil.getAttributeSegment((IDOMNode)target.getAttributeNode(attrName), CustomValidatorUtil.ATTR_REGION_NAME);
+ return new ValidationMessage("Undefined attribute name", segment.getOffset(), segment.getLength(), ValidationMessage.WARNING);
+ }
+
+}
diff --git a/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedTagValidator.java b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedTagValidator.java
new file mode 100644
index 0000000000..688656e39b
--- /dev/null
+++ b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/CustomExtendedTagValidator.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.html.ui.tests.validation;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.wst.html.core.internal.validate.Segment;
+import org.eclipse.wst.html.core.validate.extension.CustomValidatorUtil;
+import org.eclipse.wst.html.core.validate.extension.IHTMLCustomTagValidator;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.junit.Assert;
+
+public class CustomExtendedTagValidator implements IHTMLCustomTagValidator{
+ private String currentFileLocation;
+
+ public boolean canValidate(IDOMElement target) {
+ if (target.getLocalName().startsWith("eclipse")) {
+ return true;
+ }
+ return false;
+ }
+
+ public void init(IStructuredDocument doc) {
+ currentFileLocation = getResource(doc);
+ }
+
+ public ValidationMessage validateTag(IDOMElement target) {
+ Assert.assertEquals(currentFileLocation, getResource(target.getStructuredDocument()));
+ String tagName = target.getLocalName();
+ if (tagName.contains("thym")) {
+ Segment segment = CustomValidatorUtil.getTagSegment(target, CustomValidatorUtil.SEG_START_TAG_NAME);
+ return new ValidationMessage("Thym is available only with external installation", segment.getOffset(), segment.getLength(), ValidationMessage.ERROR);
+ }
+ return null;
+ }
+
+ private String getResource(IDocument document) {
+ if (document == null) return null;
+ IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
+ try {
+ if (sModel != null) {
+ return sModel.getBaseLocation();
+ }
+ }
+ finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/TestHTMLValidator.java b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/TestHTMLValidator.java
index a9c9626bc6..09ef15ceef 100644
--- a/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/TestHTMLValidator.java
+++ b/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/validation/TestHTMLValidator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2011 IBM Corporation and others.
+ * Copyright (c) 2009, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,10 +7,12 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Red Hat, Inc. - test for external validator
*******************************************************************************/
package org.eclipse.wst.html.ui.tests.validation;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -21,6 +23,7 @@ import junit.framework.TestSuite;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.wst.html.core.internal.validation.HTMLValidator;
import org.eclipse.wst.html.ui.tests.ProjectUtil;
@@ -142,6 +145,46 @@ public class TestHTMLValidator extends TestCase {
}
}
+ public void testExtendedValidator() throws Exception{
+ IFile testFile = fProject.getFile("validCustomTags.html");
+ performExternalValidatorTest(testFile, false);
+ testFile = fProject.getFile("customTags.html");
+ performExternalValidatorTest(testFile, true);
+ testFile = fProject.getFile("invalidAttrTestFile.html");
+ performExternalValidatorTest(testFile, true);
+ }
+
+ private void performExternalValidatorTest(IFile testFile, boolean errorExpected) throws IOException, CoreException {
+ IStructuredModel model = null;
+
+ try {
+ assertTrue("Test file " + testFile + " does not exist", testFile.exists());
+
+ //get the document
+ model = StructuredModelManager.getModelManager().getModelForEdit(testFile);
+
+ //set up for fValidator
+ WorkbenchContext context = new WorkbenchContext();
+ List fileList = new ArrayList();
+ fileList.add(testFile.getFullPath().toPortableString());
+ context.setValidationFileURIs(fileList);
+
+ //validate clean file
+ TestReporter reporter = new TestReporter();
+ fValidator.validate(context, reporter);
+ if (errorExpected) {
+ assertTrue("There should be validation errors on " + testFile, reporter.isMessageReported());
+ } else {
+ assertFalse("There should be no validation errors on " + testFile, reporter.isMessageReported());
+ }
+
+ } finally {
+ if(model != null) {
+ model.releaseFromEdit();
+ }
+ }
+ }
+
/**
* Regression test for Bug 298472
*
diff --git a/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/customTags.html b/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/customTags.html
new file mode 100644
index 0000000000..8848937030
--- /dev/null
+++ b/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/customTags.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="ISO-8859-1">
+<title>Eclipse</title>
+</head>
+<body>
+ <eclipse>
+ <eclipse-wtp plugins="900"/>
+ <eclipse-jsdt plugins="www"/>
+ <eclipse-thym plugins="8"/>
+ </eclipse>
+</body>
+</html> \ No newline at end of file
diff --git a/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/invalidAttrTestFile.html b/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/invalidAttrTestFile.html
new file mode 100644
index 0000000000..0736811194
--- /dev/null
+++ b/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/invalidAttrTestFile.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="ISO-8859-1">
+<title>Eclipse</title>
+</head>
+<body attr="qqq">
+</body>
+</html> \ No newline at end of file
diff --git a/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/validCustomTags.html b/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/validCustomTags.html
new file mode 100644
index 0000000000..1d61e7ef67
--- /dev/null
+++ b/tests/org.eclipse.wst.html.ui.tests/testresources/TestHTMLValidator/validCustomTags.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="ISO-8859-1">
+<title>Eclipse</title>
+</head>
+<body pr-a="qqq">
+ <eclipse>
+ <eclipse-jdt plugins="900"/>
+ <eclipse-m2e/>
+ </eclipse>
+</body>
+</html> \ No newline at end of file

Back to the top