diff options
Diffstat (limited to 'bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java')
-rw-r--r-- | bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java | 445 |
1 files changed, 0 insertions, 445 deletions
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 deleted file mode 100644 index 9265639e2e..0000000000 --- a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/validate/SyntaxValidator.java +++ /dev/null @@ -1,445 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2011 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.wst.html.core.internal.validate; - -import java.util.Iterator; - -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.provisional.HTML50Namespace; -import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; -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.xml.core.internal.contentmodel.CMElementDeclaration; -import org.eclipse.wst.xml.core.internal.document.InvalidCharacterException; -import org.eclipse.wst.xml.core.internal.document.SourceValidator; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; -import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; - -class SyntaxValidator extends PrimeValidator implements ErrorState { - - - static private boolean isValidRegion(ITextRegion rgn) { - String type = rgn.getType(); - if (type == null) - return false; // no type is invalid. - if (type == DOMRegionContext.XML_END_TAG_OPEN || type == DOMRegionContext.XML_TAG_NAME || type == DOMRegionContext.XML_TAG_CLOSE) { - return true; - } - return false; - } - - static private String getTagName(IStructuredDocumentRegion tag) { - ITextRegionList regions = tag.getRegions(); - Iterator iter = regions.iterator(); - while (iter.hasNext()) { - ITextRegion rgn = (ITextRegion) iter.next(); - if (rgn.getType() == DOMRegionContext.XML_TAG_NAME) - return tag.getText(rgn); - } - return "";//$NON-NLS-1$ - } - - static private boolean isEmptyContent(CMElementDeclaration decl) { - return (decl != null) && (decl.getContentType() == CMElementDeclaration.EMPTY); - } - - public SyntaxValidator() { - super(); - } - - public boolean isAdapterForType(Object type) { - return ((type == SyntaxValidator.class) || super.isAdapterForType(type)); - } - - class ElementInfo { - public ElementInfo() { - super(); - } - - public IDOMElement target = null; - public CMElementDeclaration decl = null; - public IStructuredDocumentRegion startTag = null; - public IStructuredDocumentRegion endTag = null; - public boolean hasStartTag() {return startTag != null;} - public boolean hasEndTag() {return endTag != null;} - public boolean isXHTML = false; - public boolean isXHTML5 = false; - } - - public void validate(IndexedRegion indexedNode) { - Node node = (Node) indexedNode; - validateChildren(node); - - if (node.getNodeType() != Node.ELEMENT_NODE) - return; - if (!(node instanceof IDOMElement)) - return; - - ElementInfo info = new ElementInfo(); - info.target = (IDOMElement) node; - - // gather information to validate from target at once. - getInfo(info); - - validateTags(info); - if (info.target.isGlobalTag()) { - validateNames(info); - if (info.decl != null && info.isXHTML) { - validateTagCase(info); - } - } - - //validate the syntax of the attributes - validateAttributes(info); - } - - private void getInfo(ElementInfo info) { - info.decl = CMUtil.getDeclaration(info.target); - info.startTag = info.target.getStartStructuredDocumentRegion(); - info.endTag = info.target.getEndStructuredDocumentRegion(); - - Document doc = info.target.getOwnerDocument(); - if (!(doc instanceof IDOMDocument)) - return; - String typeid = ((IDOMDocument) doc).getDocumentTypeId(); - if (typeid != null) { - if (typeid.trim().length()!= 0){ - HTMLDocumentTypeEntry entry = HTMLDocumentTypeRegistry.getInstance().getEntry(typeid); - info.isXHTML = (entry != null && entry.isXMLType()); - } - else { - info.isXHTML = getXMLTarget(doc); - info.isXHTML5 = info.isXHTML; - } - } - } - - private boolean getXMLTarget(Document doc) { - if (doc == null) - return false; - Node child = doc.getFirstChild(); - while (child != null) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - if (child.getNodeName().equalsIgnoreCase("html")){ - if (child.getAttributes()!= null){ - NamedNodeMap attrs = child.getAttributes(); - for (int i = 0; i < attrs.getLength(); i++) { - Attr a = (Attr) attrs.item(i); - if (a.getName().equalsIgnoreCase(HTML50Namespace.ATTR_NAME_XMLNS)) - return true; - } - } - return false; - } - - } - child = child.getNextSibling(); - } - return false; - } - - class TagErrorInfoImpl extends AbstractErrorInfo { - private String hint = null; - - public TagErrorInfoImpl(int state, IStructuredDocumentRegion tag, String hint) { - super(state, new Segment(tag)); - this.hint = hint; - } - - public String getHint() { - return hint; - } - - public short getTargetType() { - return Node.ELEMENT_NODE; - } - } - - private boolean isEndTagCorrupted(ElementInfo info) { - ITextRegionList regions = info.endTag.getRegions(); - if (regions == null || regions.isEmpty()) - return false; - Iterator iter = regions.iterator(); - while (iter.hasNext()) { - ITextRegion rgn = (ITextRegion) iter.next(); - if (!isValidRegion(rgn)) - return true; // found invalid region type. - } - return false; // all regions are valid. - } - - private String getEndTagFullText(ElementInfo info) { - String hint = "";//$NON-NLS-1$ - ITextRegionList regions = info.endTag.getRegions(); - Iterator iter = regions.iterator(); - while (iter.hasNext()) { - ITextRegion rgn = (ITextRegion) iter.next(); - String type = rgn.getType(); - if (type == null) - continue; - if (type == DOMRegionContext.XML_END_TAG_OPEN || type == DOMRegionContext.XML_TAG_CLOSE) - continue; - hint += info.endTag.getFullText(rgn); - } - return hint; - } - - private void reportCorruptedEndTagError(ElementInfo info) { - String hint = getEndTagFullText(info); - TagErrorInfoImpl error = new TagErrorInfoImpl(UNDEFINED_NAME_ERROR, info.endTag, hint); - this.reporter.report(error); - } - - private void validateTags(ElementInfo info) { - if (info.hasStartTag()) { - if (!info.target.isStartTagClosed()) { - // Mark the whole START tag as an error segment. - Segment errorSeg = new Segment(info.startTag); - report(UNCLOSED_TAG_ERROR, errorSeg, info.target); - } - } - else { - if (info.hasEndTag()) { - if (info.decl != null) { - //if xhtml then must have end tag - //else determine if end tag is omissible - if (info.isXHTML) { - Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_END_TAG_NAME); - report(MISSING_START_TAG_ERROR, errorSeg, info.target); - } else { - //determine if the end tag is omissible - boolean canOmitStartTag = false; - if(info.decl instanceof HTMLPropertyDeclaration) { - int omitType = ((HTMLPropertyDeclaration)info.decl).getOmitType(); - canOmitStartTag = omitType == HTMLElementDeclaration.OMIT_BOTH; - } - - if (!canOmitStartTag && !info.target.hasChildNodes()) { - if (info.target.isContainer()) { - // Set the error mark to the start of the element. - Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_END_TAG); - report(MISSING_START_TAG_ERROR, errorSeg, info.target); - } - else { - // Mark the whole END tag as an error segment. - Segment errorSeg = new Segment(info.endTag); - report(UNNECESSARY_END_TAG_ERROR, errorSeg, info.target); - } - } - } - } - } - } - - if (info.hasEndTag()) { - if (!info.target.isClosed()) { - // Set the whole END tag as error segment. - Segment errorSeg = new Segment(info.endTag); - report(UNCLOSED_END_TAG_ERROR, errorSeg, info.target); - } - } - else { - if (info.isXHTML) { // XHTML - //if editor closed during validation this could be null - IStructuredDocumentRegion structRegion = info.target.getStartStructuredDocumentRegion(); - if (!info.target.isEmptyTag() && structRegion != null && DOMRegionContext.XML_TAG_OPEN.equals(structRegion.getFirstRegion().getType())) { - /* - * https://bugs.eclipse.org/bugs/show_bug.cgi?id=248963 : - * report empty tags not written as such, but only when - * they follow actual XML/HTML syntax - */ - if (isEmptyContent(info.decl)) { - // EMPTY element should be written in <.../> form - Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_START_TAG); - report(INVALID_EMPTY_ELEMENT_TAG, errorSeg, info.target); - } - else { - // end tag is required. - Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_START_TAG); - report(MISSING_END_TAG_ERROR, errorSeg, info.target); - } - } - } - else { // HTML - if (info.hasStartTag()) { - if (info.decl != null && CMUtil.isHTML(info.decl) && !info.target.isEmptyTag() && !CMUtil.isEndTagOmissible(info.decl) && DOMRegionContext.XML_TAG_OPEN.equals(info.startTag.getFirstRegion().getType())) { - // Set the error mark to the end of the element. - Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_START_TAG); - report(MISSING_END_TAG_ERROR, errorSeg, info.target); - } - } - } - } - } - - /* perform validation about tag name definition. */ - private void validateNames(ElementInfo info) { - boolean corrupted = info.hasEndTag() && isEndTagCorrupted(info); - if (info.decl == null) { - // If no declaration is retrieved, the target is really - // unknown element. - if (!info.hasStartTag() && corrupted) { - reportCorruptedEndTagError(info); - } - else { - Segment errorSeg = FMUtil.getSegment(info.target, FMUtil.SEG_START_TAG_NAME); - report(UNDEFINED_NAME_ERROR, errorSeg, info.target); - } - } - else { - // Even if a declaration could be retrieved, if the end - // tag is corrupted, it should be reported as undefined - // name. (D202493) - if (corrupted) { - reportCorruptedEndTagError(info); - } - } - } - - /* perform validation tag case only for XHTML document */ - private void validateTagCase(ElementInfo info) { - String declared = info.decl.getElementName(); - String startTagName = "";//$NON-NLS-1$ - String endTagName = "";//$NON-NLS-1$ - if (declared == null) - return; - - if (info.isXHTML5){ - if (info.hasStartTag()) { - startTagName = getTagName(info.startTag); - if (info.hasEndTag()) { - endTagName = getTagName(info.endTag); - if (!endTagName.equals(startTagName)){ - TagErrorInfoImpl error = new TagErrorInfoImpl(MISMATCHED_ERROR, info.endTag, endTagName); - this.reporter.report(error); - } - } - } - - } - else - { - // start tag - if (info.hasStartTag()) { - startTagName = getTagName(info.startTag); - if (!declared.equals(startTagName)) { - TagErrorInfoImpl error = new TagErrorInfoImpl(MISMATCHED_ERROR, info.startTag, startTagName); - this.reporter.report(error); - } - } - // end tag - if (info.hasEndTag()) { - endTagName = getTagName(info.endTag); - if (!info.hasStartTag() || (!endTagName.equals(startTagName))) { - if (!declared.equals(endTagName)) { - TagErrorInfoImpl error = new TagErrorInfoImpl(MISMATCHED_ERROR, info.endTag, endTagName); - this.reporter.report(error); - } - } - } - } - - } - - private void validateChildren(Node target) { - if ((target.getNodeType() == Node.ELEMENT_NODE) && CMUtil.isForeign((Element) target)) - return; - - for (Node child = target.getFirstChild(); child != null; child = child.getNextSibling()) { - switch (child.getNodeType()) { - case Node.TEXT_NODE : - { - IDOMNode text = (IDOMNode) child; - int charOffset = validateTextSource(text); - if (charOffset >= 0) { - charOffset += text.getStartOffset(); - Segment errorSeg = new Segment(charOffset, 1); - if (errorSeg != null) - report(INVALID_CHAR_ERROR, errorSeg, text); - } - break; - } - case Node.COMMENT_NODE : - case Node.DOCUMENT_TYPE_NODE : - case Node.PROCESSING_INSTRUCTION_NODE : - case Node.CDATA_SECTION_NODE : - { - IDOMNode tag = (IDOMNode) child; - if (!tag.isClosed()) { - Segment errorSeg = FMUtil.getSegment(tag, FMUtil.SEG_WHOLE_TAG); - if (errorSeg != null) - report(UNCLOSED_TAG_ERROR, errorSeg, tag); - } - break; - } - default : - break; - } - } - } - - private int validateTextSource(IDOMNode text) { - try { - SourceValidator validator = new SourceValidator(text); - validator.validateSource(text.getSource()); - } - catch (InvalidCharacterException ex) { - return ex.getOffset(); - } - return -1; - } - - /** - * <p>Used to validate the syntax of the arguments in a tag.</p> - * - * @param info the <code>ElementInfo</code> about the tag to validate - */ - private void validateAttributes(ElementInfo info) { - if(info != null && info.hasStartTag()) { - ITextRegionList list = info.startTag.getRegions(); - - //for each region in the tag, these make up the arguments - for(int i = 0; i < list.size(); ++i) { - ITextRegion region = list.get(i); - String type = region.getType(); - - //if the type is undefined then there is a syntax error - if(type == DOMRegionContext.UNDEFINED) { - String invalidText = info.startTag.getFullText(region).trim(); - Segment errorSeg = new Segment(info.startTag.getStartOffset() + region.getStart(), invalidText.length()); - report(INVALID_TEXT_IN_ELEM_ERROR, errorSeg, info.target, new String[]{invalidText}, new String[0]); - } - } - } - } - - private void report(int state, Segment errorSeg, Node node) { - ErrorInfo info = new ErrorInfoImpl(state, errorSeg, node); - reporter.report(info); - } - - private void report(int state, Segment errorSeg, Node node, String[] preTargetMsgInjections, String[] postTargetMsgInjections) { - ErrorInfo info = new ErrorInfoImpl(state, errorSeg, node, preTargetMsgInjections, postTargetMsgInjections); - reporter.report(info); - } -} |