diff options
Diffstat (limited to 'bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/MarkupValidator.java')
-rw-r--r-- | bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/MarkupValidator.java | 1037 |
1 files changed, 0 insertions, 1037 deletions
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/MarkupValidator.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/MarkupValidator.java deleted file mode 100644 index 8f23c7ff0b..0000000000 --- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/MarkupValidator.java +++ /dev/null @@ -1,1037 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2001, 2008 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 - * Jens Lukowski/Innoopract - initial renaming/restructuring - * - *******************************************************************************/ -package org.eclipse.wst.xml.ui.internal.validation; - -import java.util.Locale; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceProxy; -import org.eclipse.core.resources.IResourceProxyVisitor; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.content.IContentDescription; -import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.quickassist.IQuickAssistProcessor; -import org.eclipse.osgi.util.NLS; -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.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.utils.StringUtils; -import org.eclipse.wst.sse.ui.internal.reconcile.AbstractStructuredTextReconcilingStrategy; -import org.eclipse.wst.sse.ui.internal.reconcile.ReconcileAnnotationKey; -import org.eclipse.wst.sse.ui.internal.reconcile.validator.AnnotationInfo; -import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator; -import org.eclipse.wst.sse.ui.internal.reconcile.validator.IncrementalReporter; -import org.eclipse.wst.validation.AbstractValidator; -import org.eclipse.wst.validation.ValidationResult; -import org.eclipse.wst.validation.ValidationState; -import org.eclipse.wst.validation.internal.core.Message; -import org.eclipse.wst.validation.internal.core.ValidationException; -import org.eclipse.wst.validation.internal.operations.IWorkbenchContext; -import org.eclipse.wst.validation.internal.operations.LocalizedMessage; -import org.eclipse.wst.validation.internal.provisional.core.IMessage; -import org.eclipse.wst.validation.internal.provisional.core.IReporter; -import org.eclipse.wst.validation.internal.provisional.core.IValidationContext; -import org.eclipse.wst.validation.internal.provisional.core.IValidator; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; -import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext; -import org.eclipse.wst.xml.ui.internal.Logger; -import org.eclipse.wst.xml.ui.internal.XMLUIMessages; -import org.eclipse.wst.xml.ui.internal.correction.ProblemIDsXML; -import org.w3c.dom.Node; - -/** - * Basic XML syntax checking step. - */ -public class MarkupValidator extends AbstractValidator implements IValidator, ISourceValidator { - private String DQUOTE = "\""; //$NON-NLS-1$ - private String SQUOTE = "'"; //$NON-NLS-1$ - private final String QUICKASSISTPROCESSOR = IQuickAssistProcessor.class.getName(); - - private IDocument fDocument; - - private IContentType fRootContentType = null; - - private int SEVERITY_ATTRIBUTE_HAS_NO_VALUE = IMessage.HIGH_SEVERITY; - private int SEVERITY_END_TAG_WITH_ATTRIBUTES = IMessage.HIGH_SEVERITY; - private int SEVERITY_INVALID_WHITESPACE_BEFORE_TAGNAME = IMessage.HIGH_SEVERITY; - private int SEVERITY_MISSING_CLOSING_BRACKET = IMessage.HIGH_SEVERITY; - private int SEVERITY_MISSING_CLOSING_QUOTE = IMessage.HIGH_SEVERITY; - private int SEVERITY_MISSING_END_TAG = IMessage.HIGH_SEVERITY; - private int SEVERITY_MISSING_START_TAG = IMessage.HIGH_SEVERITY; - private int SEVERITY_MISSING_QUOTES = IMessage.HIGH_SEVERITY; - private int SEVERITY_NAMESPACE_IN_PI_TARGET = IMessage.HIGH_SEVERITY; - private int SEVERITY_TAG_NAME_MISSING = IMessage.HIGH_SEVERITY; - private int SEVERITY_WHITESPACE_AT_START = IMessage.HIGH_SEVERITY; - - private void addAttributeError(String messageText, String attributeValueText, int start, int length, int problemId, IStructuredDocumentRegion sdRegion, IReporter reporter, int messageSeverity) { - - if (sdRegion.isDeleted()) { - return; - } - - int lineNo = getLineNumber(start); - LocalizedMessage message = new LocalizedMessage(messageSeverity, messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(lineNo); - - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(problemId); - processor.setAdditionalFixInfo(attributeValueText); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - } - - private void checkAttributesInEndTag(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - - if (structuredDocumentRegion.isDeleted()) { - return; - } - - ITextRegionList textRegions = structuredDocumentRegion.getRegions(); - int errorCount = 0; - int start = structuredDocumentRegion.getEndOffset(); - int end = structuredDocumentRegion.getEndOffset(); - for (int i = 0; (i < textRegions.size()) && (errorCount < AbstractStructuredTextReconcilingStrategy.ELEMENT_ERROR_LIMIT) && !structuredDocumentRegion.isDeleted(); i++) { - ITextRegion textRegion = textRegions.get(i); - if ((textRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) || (textRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS) || (textRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)) { - if (start > structuredDocumentRegion.getStartOffset(textRegion)) { - start = structuredDocumentRegion.getStartOffset(textRegion); - } - end = structuredDocumentRegion.getEndOffset(textRegion); - errorCount++; - } - } - // create one error for all attributes in the end tag - if (errorCount > 0) { - // Position p = new Position(start, end - start); - String messageText = XMLUIMessages.End_tag_has_attributes; - LocalizedMessage message = new LocalizedMessage(SEVERITY_END_TAG_WITH_ATTRIBUTES, messageText); - message.setOffset(start); - message.setLength(end - start); - message.setLineNo(getLineNumber(start)); - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.AttrsInEndTag); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - } - } - - - private void checkClosingBracket(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - - if (structuredDocumentRegion.isDeleted()) { - return; - } - - ITextRegionList regions = structuredDocumentRegion.getRegions(); - ITextRegion r = null; - boolean closed = false; - for (int i = 0; (i < regions.size()) && !structuredDocumentRegion.isDeleted(); i++) { - r = regions.get(i); - if ((r.getType() == DOMRegionContext.XML_TAG_CLOSE) || (r.getType() == DOMRegionContext.XML_EMPTY_TAG_CLOSE)) { - closed = true; - } - } - if (!closed) { - - String messageText = XMLUIMessages.ReconcileStepForMarkup_6; - - int start = structuredDocumentRegion.getStartOffset(); - int length = structuredDocumentRegion.getText().trim().length(); - int lineNo = getLineNumber(start); - - LocalizedMessage message = new LocalizedMessage(SEVERITY_MISSING_CLOSING_BRACKET , messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(lineNo); - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.MissingClosingBracket); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - } - } - - private void checkEmptyTag(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - - if (structuredDocumentRegion.isDeleted()) { - return; - } - - // navigate to name - ITextRegionList regions = structuredDocumentRegion.getRegions(); - if (regions.size() == 2) { - // missing name region - if ((regions.get(0).getType() == DOMRegionContext.XML_TAG_OPEN) && (regions.get(1).getType() == DOMRegionContext.XML_TAG_CLOSE)) { - String messageText = XMLUIMessages.ReconcileStepForMarkup_3; - int start = structuredDocumentRegion.getStartOffset(); - int length = structuredDocumentRegion.getLength(); - int lineNo = getLineNumber(start); - - LocalizedMessage message = new LocalizedMessage(SEVERITY_TAG_NAME_MISSING , messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(lineNo); - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.EmptyTag); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - } - } - } - - private int getLineNumber(int start) { - int lineNo = -1; - try { - lineNo = getDocument().getLineOfOffset(start) + 1; - } - catch (BadLocationException e) { - Logger.logException(e); - } - return lineNo; - } - - private void checkForAttributeValue(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - if (structuredDocumentRegion.isDeleted()) { - return; - } - - // check for attributes without a value - // track the attribute/equals/value sequence using a state of 0, 1 ,2 - // representing the name, =, and value, respectively - int attrState = 0; - ITextRegionList textRegions = structuredDocumentRegion.getRegions(); - // ReconcileAnnotationKey key = createKey(structuredDocumentRegion, - // getScope()); - - int errorCount = 0; - for (int i = 0; (i < textRegions.size()) && (errorCount < AbstractStructuredTextReconcilingStrategy.ELEMENT_ERROR_LIMIT); i++) { - ITextRegion textRegion = textRegions.get(i); - if ((textRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) || isTagCloseTextRegion(textRegion)) { - // dangling name and '=' - if ((attrState == 2) && (i >= 2)) { - // create annotation - ITextRegion nameRegion = textRegions.get(i - 2); - if (!(nameRegion instanceof ITextRegionContainer)) { - Object[] args = {structuredDocumentRegion.getText(nameRegion)}; - String messageText = NLS.bind(XMLUIMessages.Attribute__is_missing_a_value, args); - - int start = structuredDocumentRegion.getStartOffset(nameRegion); - int end = structuredDocumentRegion.getEndOffset(); - int lineNo = getLineNumber(start); - int textLength = structuredDocumentRegion.getText(nameRegion).trim().length(); - - LocalizedMessage message = new LocalizedMessage(SEVERITY_ATTRIBUTE_HAS_NO_VALUE , messageText); - message.setOffset(start); - message.setLength(textLength); - message.setLineNo(lineNo); - - // quick fix info - ITextRegion equalsRegion = textRegions.get(i - 2 + 1); - int insertOffset = structuredDocumentRegion.getTextEndOffset(equalsRegion) - end; - Object[] additionalFixInfo = {structuredDocumentRegion.getText(nameRegion), new Integer(insertOffset)}; - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.MissingAttrValue); - processor.setAdditionalFixInfo(additionalFixInfo); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - errorCount++; - } - } - // name but no '=' (XML only) - else if ((attrState == 1) && (i >= 1)) { - // create annotation - ITextRegion previousRegion = textRegions.get(i - 1); - if (!(previousRegion instanceof ITextRegionContainer)) { - Object[] args = {structuredDocumentRegion.getText(previousRegion)}; - String messageText = NLS.bind(XMLUIMessages.Attribute__has_no_value, args); - int start = structuredDocumentRegion.getStartOffset(previousRegion); - int textLength = structuredDocumentRegion.getText(previousRegion).trim().length(); - int lineNo = getLineNumber(start); - - LocalizedMessage message = new LocalizedMessage(SEVERITY_ATTRIBUTE_HAS_NO_VALUE, messageText); - message.setOffset(start); - message.setLength(textLength); - message.setLineNo(lineNo); - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.NoAttrValue); - processor.setAdditionalFixInfo(structuredDocumentRegion.getText(previousRegion)); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - - errorCount++; - } - } - attrState = 1; - } - else if (textRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS) { - attrState = 2; - } - else if (textRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) { - attrState = 0; - } - } - - } - - private void checkForSpaceBeforeName(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - - if (structuredDocumentRegion.isDeleted()) { - return; - } - - String sdRegionText = structuredDocumentRegion.getFullText(); - if (sdRegionText.startsWith(" ")) { //$NON-NLS-1$ - IStructuredDocumentRegion prev = structuredDocumentRegion.getPrevious(); - if (prev != null) { - // this is possibly the case of "< tag" - if ((prev.getRegions().size() == 1) && isStartTag(prev)) { - // add the error for preceding space in tag name - String messageText = XMLUIMessages.ReconcileStepForMarkup_2; - int start = structuredDocumentRegion.getStartOffset(); - // find length of whitespace - int length = sdRegionText.trim().equals("") ? sdRegionText.length() : sdRegionText.indexOf(sdRegionText.trim()); //$NON-NLS-1$ - - LocalizedMessage message = new LocalizedMessage(SEVERITY_INVALID_WHITESPACE_BEFORE_TAGNAME , messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(getLineNumber(start)); - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.SpacesBeforeTagName); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - } - } - } - } - - private void checkNoNamespaceInPI(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - - if (structuredDocumentRegion.isDeleted()) { - return; - } - - // navigate to name - ITextRegionList regions = structuredDocumentRegion.getRegions(); - ITextRegion r = null; - int errorCount = 0; - for (int i = 0; (i < regions.size()) && (errorCount < AbstractStructuredTextReconcilingStrategy.ELEMENT_ERROR_LIMIT) && !structuredDocumentRegion.isDeleted(); i++) { - r = regions.get(i); - if (r.getType() == DOMRegionContext.XML_TAG_NAME) { - String piText = structuredDocumentRegion.getText(r); - int index = piText.indexOf(":"); //$NON-NLS-1$ - if (index != -1) { - String messageText = XMLUIMessages.ReconcileStepForMarkup_4; - int start = structuredDocumentRegion.getStartOffset(r) + index; - int length = piText.trim().length() - index; - - LocalizedMessage message = new LocalizedMessage(SEVERITY_NAMESPACE_IN_PI_TARGET , messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(getLineNumber(start)); - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.NamespaceInPI); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - - errorCount++; - } - } - } - } - - private void checkQuotesForAttributeValues(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - ITextRegionList regions = structuredDocumentRegion.getRegions(); - ITextRegion r = null; - String attrValueText = ""; //$NON-NLS-1$ - int errorCount = 0; - for (int i = 0; (i < regions.size()) && (errorCount < AbstractStructuredTextReconcilingStrategy.ELEMENT_ERROR_LIMIT); i++) { - r = regions.get(i); - if (r.getType() != DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) { - continue; - } - - attrValueText = structuredDocumentRegion.getText(r); - // attribute value includes quotes in the string - // split up attribute value on quotes - /* - * WORKAROUND till - * http://dev.icu-project.org/cgi-bin/icu-bugs/incoming?findid=5207 - * is fixed. (Also see BUG143628) - */ - - java.util.StringTokenizer st = new java.util.StringTokenizer(attrValueText, "\"'", true); //$NON-NLS-1$ - int size = st.countTokens(); - // get the pieces of the attribute value - String one = "", two = ""; //$NON-NLS-1$ //$NON-NLS-2$ - if (size > 0) { - one = st.nextToken(); - } - if (size > 1) { - two = st.nextToken(); - } - if (size > 2) { - // should be handled by parsing... - // as in we can't have an attribute value like: <element - // attr="a"b"c"/> - // and <element attr='a"b"c' /> is legal - continue; - } - - - if (size == 1) { - if (one.equals(DQUOTE) || one.equals(SQUOTE)) { - // missing closing quote - String message = XMLUIMessages.ReconcileStepForMarkup_0; - addAttributeError(message, attrValueText, structuredDocumentRegion.getStartOffset(r), attrValueText.trim().length(), ProblemIDsXML.Unclassified, structuredDocumentRegion, reporter, SEVERITY_MISSING_CLOSING_QUOTE); - errorCount++; - } - else { - // missing both - String message = XMLUIMessages.ReconcileStepForMarkup_1; - addAttributeError(message, attrValueText, structuredDocumentRegion.getStartOffset(r), attrValueText.trim().length(), ProblemIDsXML.AttrValueNotQuoted, structuredDocumentRegion, reporter, SEVERITY_MISSING_QUOTES); - errorCount++; - } - } - else if (size == 2) { - if ((one.equals(SQUOTE) && !two.equals(SQUOTE)) || (one.equals(DQUOTE) && !two.equals(DQUOTE))) { - // missing closing quote - String message = XMLUIMessages.ReconcileStepForMarkup_0; - addAttributeError(message, attrValueText, structuredDocumentRegion.getStartOffset(r), attrValueText.trim().length(), ProblemIDsXML.Unclassified, structuredDocumentRegion, reporter, SEVERITY_MISSING_CLOSING_QUOTE); - errorCount++; - } - } - } - // end of region for loop - } - - private void checkStartEndTagPairs(IStructuredDocumentRegion sdRegion, IReporter reporter) { - - if (sdRegion.isDeleted()) { - return; - } - - // check start/end tag pairs - IDOMNode xmlNode = getXMLNode(sdRegion); - - if (xmlNode == null) { - return; - } - - boolean selfClosed = false; - String tagName = null; - - /** - * For tags that aren't meant to be EMPTY, make sure it's empty or has an end tag - */ - if (xmlNode.isContainer()) { - IStructuredDocumentRegion endRegion = xmlNode.getEndStructuredDocumentRegion(); - if (endRegion == null) { - IStructuredDocumentRegion startRegion = xmlNode.getStartStructuredDocumentRegion(); - if (startRegion != null && !startRegion.isDeleted() && DOMRegionContext.XML_TAG_OPEN.equals(startRegion.getFirstRegion().getType())) { - // analyze the tag (check self closing) - ITextRegionList regions = startRegion.getRegions(); - ITextRegion r = null; - int start = sdRegion.getStart(); - int length = sdRegion.getTextLength(); - for (int i = 0; i < regions.size(); i++) { - r = regions.get(i); - if (r.getType() == DOMRegionContext.XML_TAG_NAME) { - tagName = sdRegion.getText(r); - start = sdRegion.getStartOffset(r); - length = r.getTextLength(); - } - else if (r.getType() == DOMRegionContext.XML_EMPTY_TAG_CLOSE) { - selfClosed = true; - } - } - - - if (!selfClosed && (tagName != null)) { - Object[] args = {tagName}; - String messageText = NLS.bind(XMLUIMessages.Missing_end_tag_, args); - - int lineNumber = getLineNumber(start); - - IMessage message = new LocalizedMessage(SEVERITY_MISSING_END_TAG , messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(lineNumber); - - if (reporter instanceof IncrementalReporter) { - Object[] additionalFixInfo = getStartEndFixInfo(xmlNode, tagName, r); - - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.MissingEndTag); - processor.setAdditionalFixInfo(additionalFixInfo); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - } - } - } - else { - IStructuredDocumentRegion startRegion = xmlNode.getStartStructuredDocumentRegion(); - if (startRegion == null || startRegion.isDeleted()) { - // analyze the tag (check self closing) - ITextRegionList regions = endRegion.getRegions(); - ITextRegion r = null; - int start = sdRegion.getStart(); - int length = sdRegion.getTextLength(); - for (int i = 0; i < regions.size(); i++) { - r = regions.get(i); - if (r.getType() == DOMRegionContext.XML_TAG_NAME) { - tagName = sdRegion.getText(r); - start = sdRegion.getStartOffset(r); - length = r.getTextLength(); - } - } - - if (tagName != null) { - Object[] args = {tagName}; - String messageText = NLS.bind(XMLUIMessages.Missing_start_tag_, args); - - int lineNumber = getLineNumber(start); - - IMessage message = new LocalizedMessage(SEVERITY_MISSING_START_TAG, messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(lineNumber); - - if (reporter instanceof IncrementalReporter) { - Object[] additionalFixInfo = getStartEndFixInfo(xmlNode, tagName, r); - - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.MissingStartTag); - processor.setAdditionalFixInfo(additionalFixInfo); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - } - } - } - - } - /* - * Check for an end tag that has no start tag - */ - else { - IStructuredDocumentRegion startRegion = xmlNode.getStartStructuredDocumentRegion(); - if (startRegion == null) { - IStructuredDocumentRegion endRegion = xmlNode.getEndStructuredDocumentRegion(); - if (!endRegion.isDeleted()) { - // get name - ITextRegionList regions = endRegion.getRegions(); - ITextRegion r = null; - for (int i = 0; i < regions.size(); i++) { - r = regions.get(i); - if (r.getType() == DOMRegionContext.XML_TAG_NAME) { - tagName = sdRegion.getText(r); - } - } - - if (!selfClosed && (tagName != null)) { - String messageText = StringUtils.unpack(XMLUIMessages.Indicate_no_grammar_specified_severities)[0]; - - int start = sdRegion.getStart(); - int lineNumber = getLineNumber(start); - - // SEVERITY_STRUCTURE == IMessage.HIGH_SEVERITY - IMessage message = new LocalizedMessage(IMessage.HIGH_SEVERITY, messageText); - message.setOffset(start); - message.setLength(sdRegion.getTextLength()); - message.setLineNo(lineNumber); - - reporter.addMessage(this, message); - } - } - } - } - } - - private Object[] getStartEndFixInfo(IDOMNode xmlNode, String tagName, ITextRegion r) { - // quick fix info - String tagClose = "/>"; //$NON-NLS-1$ - int tagCloseOffset = xmlNode.getFirstStructuredDocumentRegion().getEndOffset(); - if ((r != null) && (r.getType() == DOMRegionContext.XML_TAG_CLOSE)) { - tagClose = "/"; //$NON-NLS-1$ - tagCloseOffset--; - } - IDOMNode firstChild = (IDOMNode) xmlNode.getFirstChild(); - while ((firstChild != null) && (firstChild.getNodeType() == Node.TEXT_NODE)) { - firstChild = (IDOMNode) firstChild.getNextSibling(); - } - int endOffset = xmlNode.getEndOffset(); - int firstChildStartOffset = firstChild == null ? endOffset : firstChild.getStartOffset(); - Object[] additionalFixInfo = {tagName, tagClose, new Integer(tagCloseOffset), new Integer(xmlNode.getFirstStructuredDocumentRegion().getEndOffset()), // startTagEndOffset - new Integer(firstChildStartOffset), // firstChildStartOffset - new Integer(endOffset)}; // endOffset - return additionalFixInfo; - } - - private void checkStartingSpaceForPI(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - - if (structuredDocumentRegion.isDeleted()) { - return; - } - - IStructuredDocumentRegion prev = structuredDocumentRegion.getPrevious(); - if ((prev != null) && prev.getStartOffset() == 0) { - if (prev.getType() == DOMRegionContext.XML_CONTENT) { - String messageText = XMLUIMessages.ReconcileStepForMarkup_5; - int start = prev.getStartOffset(); - int length = prev.getLength(); - - LocalizedMessage message = new LocalizedMessage(SEVERITY_WHITESPACE_AT_START , messageText); - message.setOffset(start); - message.setLength(length); - message.setLineNo(getLineNumber(start)); - - if (reporter instanceof IncrementalReporter) { - MarkupQuickAssistProcessor processor = new MarkupQuickAssistProcessor(); - processor.setProblemId(ProblemIDsXML.SpacesBeforePI); - message.setAttribute(QUICKASSISTPROCESSOR, processor); - - AnnotationInfo info = new AnnotationInfo(message); - ((IncrementalReporter) reporter).addAnnotationInfo(this, info); - } - else { - reporter.addMessage(this, message); - } - // Position p = new Position(start, length); - // - // ReconcileAnnotationKey key = - // createKey(structuredDocumentRegion, getScope()); - // TemporaryAnnotation annotation = new TemporaryAnnotation(p, - // SEVERITY_SYNTAX_ERROR, message, key, - // ProblemIDsXML.SpacesBeforePI); - // results.add(annotation); - } - } - } - - public int getScope() { - return ReconcileAnnotationKey.PARTIAL; - } - - private IDOMNode getXMLNode(IStructuredDocumentRegion sdRegion) { - - if (sdRegion == null) { - return null; - } - - IStructuredModel xModel = null; - IDOMNode xmlNode = null; - // get/release models should always be in a try/finally block - try { - xModel = StructuredModelManager.getModelManager().getExistingModelForRead(getDocument()); - // xModel is sometime null, when closing editor, for example - if (xModel != null) { - xmlNode = (IDOMNode) xModel.getIndexedRegion(sdRegion.getStart()); - } - } - finally { - if (xModel != null) { - xModel.releaseFromRead(); - } - } - return xmlNode; - } - - /** - * Determines whether the IStructuredDocumentRegion is a XML "end tag" - * since they're not allowed to have attribute ITextRegions - * - * @param structuredDocumentRegion - */ - private boolean isEndTag(IStructuredDocumentRegion structuredDocumentRegion) { - if ((structuredDocumentRegion == null) || structuredDocumentRegion.isDeleted()) { - return false; - } - return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_END_TAG_OPEN; - } - - /** - * Determines if the IStructuredDocumentRegion is an XML Processing - * Instruction - * - * @param structuredDocumentRegion - * - */ - private boolean isPI(IStructuredDocumentRegion structuredDocumentRegion) { - if ((structuredDocumentRegion == null) || structuredDocumentRegion.isDeleted()) { - return false; - } - return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_PI_OPEN; - } - - /** - * Determines whether the IStructuredDocumentRegion is a XML "start tag" - * since they need to be checked for proper XML attribute region sequences - * - * @param structuredDocumentRegion - * - */ - private boolean isStartTag(IStructuredDocumentRegion structuredDocumentRegion) { - if ((structuredDocumentRegion == null) || structuredDocumentRegion.isDeleted()) { - return false; - } - return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_TAG_OPEN; - } - - // Because we check the "proper" closing separately from attribute - // sequencing, we need to know what's - // an appropriate close. - private boolean isTagCloseTextRegion(ITextRegion textRegion) { - return (textRegion.getType() == DOMRegionContext.XML_TAG_CLOSE) || (textRegion.getType() == DOMRegionContext.XML_EMPTY_TAG_CLOSE); - } - - /** - * Determines if the IStructuredDocumentRegion is XML Content - * - * @param structuredDocumentRegion - * - */ - private boolean isXMLContent(IStructuredDocumentRegion structuredDocumentRegion) { - if ((structuredDocumentRegion == null) || structuredDocumentRegion.isDeleted()) { - return false; - } - return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_CONTENT; - } - - private void setDocument(IDocument doc) { - fDocument = doc; - } - - private IDocument getDocument() { - return fDocument; - } - - public void connect(IDocument document) { - setDocument(document); - } - - public void disconnect(IDocument document) { - setDocument(null); - } - - public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) { - if (getDocument() == null) { - return; - } - if (!(reporter instanceof IncrementalReporter)) { - return; - } - if (!(getDocument() instanceof IStructuredDocument)) { - return; - } - - // remove old messages - reporter.removeAllMessages(this); - - IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument).getStructuredDocumentRegions(dirtyRegion.getOffset(), dirtyRegion.getLength()); - for (int i = 0; i < regions.length; i++) { - validate(regions[i], reporter); - } - } - - public void validate(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - - if (structuredDocumentRegion == null) { - return; - } - - if (isStartTag(structuredDocumentRegion)) { - // check for attributes without a value - checkForAttributeValue(structuredDocumentRegion, reporter); - // check if started tag is ended - checkStartEndTagPairs(structuredDocumentRegion, reporter); - // check empty tag <> - checkEmptyTag(structuredDocumentRegion, reporter); - // check that each attribute has quotes - checkQuotesForAttributeValues(structuredDocumentRegion, reporter); - // check that the closing '>' is there - checkClosingBracket(structuredDocumentRegion, reporter); - } - else if (isEndTag(structuredDocumentRegion)) { - // check if ending tag was started - checkStartEndTagPairs(structuredDocumentRegion, reporter); - // check for attributes in an end tag - checkAttributesInEndTag(structuredDocumentRegion, reporter); - // check that the closing '>' is there - checkClosingBracket(structuredDocumentRegion, reporter); - } - else if (isPI(structuredDocumentRegion)) { - // check validity of processing instruction - checkStartingSpaceForPI(structuredDocumentRegion, reporter); - checkNoNamespaceInPI(structuredDocumentRegion, reporter); - } - else if (isXMLContent(structuredDocumentRegion)) { - checkForSpaceBeforeName(structuredDocumentRegion, reporter); - } - else if (isXMLDoctypeDeclaration(structuredDocumentRegion)) { - checkDocumentTypeReferences(structuredDocumentRegion, reporter); - } - } - - /** - * @param structuredDocumentRegion - * @param reporter - */ - private void checkDocumentTypeReferences(IStructuredDocumentRegion structuredDocumentRegion, IReporter reporter) { - } - - /** - * @param structuredDocumentRegion - * @return - */ - private boolean isXMLDoctypeDeclaration(IStructuredDocumentRegion structuredDocumentRegion) { - if ((structuredDocumentRegion == null) || structuredDocumentRegion.isDeleted()) { - return false; - } - return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_DECLARATION_OPEN && structuredDocumentRegion.getType().equals(DOMRegionContext.XML_DOCTYPE_DECLARATION); - } - - public void cleanup(IReporter reporter) { - fDocument = null; - } - - public void validate(IValidationContext helper, IReporter reporter) throws ValidationException { - String[] uris = helper.getURIs(); - IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot(); - if (uris.length > 0) { - IFile currentFile = null; - - for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) { - // might be called with just project path? - IPath path = new Path(uris[i]); - if (path.segmentCount() > 1) { - currentFile = wsRoot.getFile(path); - if (shouldValidate(currentFile, true)) { - validateV1File(currentFile, reporter); - } - } - else if (uris.length == 1) { - validateV1Project(helper, reporter); - } - } - } - else - validateV1Project(helper, reporter); - } - - private boolean shouldValidate(IResourceProxy proxy) { - if(proxy.getType() == IResource.FILE) { - String name = proxy.getName(); - if(name.toLowerCase(Locale.US).endsWith(".xml")) { - return true; - } - } - return shouldValidate(proxy.requestResource(), false); - } - - private boolean shouldValidate(IResource file, boolean checkExtension) { - if (file == null || !file.exists() || file.getType() != IResource.FILE) - return false; - if (checkExtension) { - String extension = file.getFileExtension(); - if (extension != null && "xml".endsWith(extension.toLowerCase(Locale.US))) - return true; - } - - IContentDescription contentDescription = null; - try { - contentDescription = ((IFile) file).getContentDescription(); - if (contentDescription != null) { - IContentType contentType = contentDescription.getContentType(); - return contentDescription != null && contentType.isKindOf(getXMLContentType()); - } - } - catch (CoreException e) { - Logger.logException(e); - } - return false; - } - - /** - * @param helper - * @param reporter - */ - private void validateV1Project(IValidationContext helper, final IReporter reporter) { - // if uris[] length 0 -> validate() gets called for each project - if (helper instanceof IWorkbenchContext) { - IProject project = ((IWorkbenchContext) helper).getProject(); - IResourceProxyVisitor visitor = new IResourceProxyVisitor() { - public boolean visit(IResourceProxy proxy) throws CoreException { - if (shouldValidate(proxy)) { - validateV1File((IFile) proxy.requestResource(), reporter); - } - return true; - } - }; - try { - // collect all jsp files for the project - project.accept(visitor, IResource.DEPTH_INFINITE); - } - catch (CoreException e) { - Logger.logException(e); - } - } - } - - - /** - * @param currentFile - * @param reporter - */ - private void validateV1File(IFile currentFile, IReporter reporter) { - Message message = new LocalizedMessage(IMessage.LOW_SEVERITY, currentFile.getFullPath().toString().substring(1)); - reporter.displaySubtask(MarkupValidator.this, message); - - IStructuredModel model = null; - try { - model = StructuredModelManager.getModelManager().getModelForRead(currentFile); - IStructuredDocument document = null; - if (model != null) { - document = model.getStructuredDocument(); - connect(document); - IStructuredDocumentRegion validationRegion = document.getFirstStructuredDocumentRegion(); - while (validationRegion != null) { - validate(validationRegion, reporter); - validationRegion = validationRegion.getNext(); - } - disconnect(document); - } - } - catch (Exception e) { - Logger.logException(e); - } - finally { - if (model != null) { - model.releaseFromRead(); - } - } - } - - /** - * @return - */ - private IContentType getXMLContentType() { - if (fRootContentType == null) { - fRootContentType = Platform.getContentTypeManager().getContentType("org.eclipse.core.runtime.xml"); - } - return fRootContentType; - } - - /* (non-Javadoc) - * @see org.eclipse.wst.validation.AbstractValidator#validate(org.eclipse.core.resources.IResource, int, org.eclipse.wst.validation.ValidationState, org.eclipse.core.runtime.IProgressMonitor) - */ - public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) { - if (resource.getType() != IResource.FILE) - return null; - ValidationResult result = new ValidationResult(); - IReporter reporter = result.getReporter(monitor); - validateV1File((IFile) resource, reporter); - return result; - } -} |