Search in sources :

Example 1 with ITextRegionContainer

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer in project webtools.sourceediting by eclipse.

the class HTMLAttributeValidator method validate.

/**
 */
public void validate(IndexedRegion node) {
    Element target = (Element) node;
    if (CMUtil.isForeign(target))
        return;
    CMElementDeclaration edec = CMUtil.getDeclaration(target);
    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);
            }
        }
    } 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)
                    // skip futher validation and begin next loop.
                    continue;
            }
            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 (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 {
                // At 1st, the name should be checked.
                if (CMUtil.isObsolete(adec)) {
                    state = ErrorState.OBSOLETE_ATTR_NAME_ERROR;
                }
                if (CMUtil.isHTML(edec) && (!CMUtil.isXHTML(edec))) {
                    // specifically.
                    if (CMUtil.isBooleanAttr(adec) && ((IDOMAttr) a).hasNameOnly())
                        // OK, keep going. No more check is needed
                        continue;
                // 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.MISMATCHED_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;
                        }
                    }
                    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.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);
                                        }
                                    }
                                }
                            }
                        }
                    } 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;
                                }
                                // exit the loop.
                                break;
                            }
                        }
                        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;
                                    }
                                    // exit the loop.
                                    break;
                                }
                            }
                            // 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;
                                }
                            } else {
                                if (CMUtil.isXHTML(edec)) {
                                    unclosedAttr = true;
                                }
                            }
                            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));
            }
        }
    }
}
Also used : IDOMAttr(org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr) IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) CMDataType(org.eclipse.wst.xml.core.internal.contentmodel.CMDataType) IConfigurationElement(org.eclipse.core.runtime.IConfigurationElement) Element(org.w3c.dom.Element) IDOMElement(org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement) Attr(org.w3c.dom.Attr) IDOMAttr(org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr) IDOMNode(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode) List(java.util.List) ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) ArrayList(java.util.ArrayList) IPath(org.eclipse.core.runtime.IPath) Path(org.eclipse.core.runtime.Path) CMNamedNodeMap(org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap) NamedNodeMap(org.w3c.dom.NamedNodeMap) IPath(org.eclipse.core.runtime.IPath) ITextRegionContainer(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer) CMElementDeclaration(org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Collection(java.util.Collection) CMAttributeDeclaration(org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration) CMNode(org.eclipse.wst.xml.core.internal.contentmodel.CMNode) CMNamedNodeMap(org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap) IResource(org.eclipse.core.resources.IResource)

Example 2 with ITextRegionContainer

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer in project webtools.sourceediting by eclipse.

the class NamespaceValidator method validate.

public void validate(IndexedRegion node) {
    Element target = (Element) node;
    if (isXMLElement(target) && hasUnknownPrefix(target)) {
        IDOMElement e = (IDOMElement) target;
        if (!isValidPrefix(e.getPrefix(), target) && !e.isCommentTag()) {
            // report unknown tag error.
            Segment errorSeg = null;
            if (e.hasStartTag())
                errorSeg = FMUtil.getSegment(e, FMUtil.SEG_START_TAG);
            else if (e.hasEndTag())
                errorSeg = FMUtil.getSegment(e, FMUtil.SEG_END_TAG);
            if (errorSeg != null)
                reporter.report(new ErrorInfoImpl(UNDEFINED_NAME_ERROR, errorSeg, e));
        }
    }
    // (2) check prefix of each attr
    NamedNodeMap attrs = target.getAttributes();
    for (int i = 0; i < attrs.getLength(); i++) {
        Node n = attrs.item(i);
        // some containers will contain languages that also use ':'
        if (!(n instanceof IDOMAttr) || ((IDOMAttr) n).getNameRegion() instanceof ITextRegionContainer)
            continue;
        IDOMAttr a = (IDOMAttr) n;
        String prefix = a.getPrefix();
        if ((prefix != null) && isUnknownAttr(a, target)) {
            // The attr has unknown prefix.  So, check it.
            if (!isValidPrefix(prefix, target)) {
                // report unknown attr error.
                ITextRegion r = a.getNameRegion();
                if (r == null)
                    continue;
                int a_offset = a.getNameRegionStartOffset();
                int a_length = a.getNameRegion().getLength();
                reporter.report(new ErrorInfoImpl(UNDEFINED_NAME_ERROR, new Segment(a_offset, a_length), a));
            }
        }
    }
}
Also used : IDOMAttr(org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr) CMNamedNodeMap(org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap) NamedNodeMap(org.w3c.dom.NamedNodeMap) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Element(org.w3c.dom.Element) IDOMElement(org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement) Node(org.w3c.dom.Node) ITextRegionContainer(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer) IDOMElement(org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement)

Example 3 with ITextRegionContainer

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer in project webtools.sourceediting by eclipse.

the class JsTranslator method translateJSNode.

/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#translateJSNode(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)
	 */
public void translateJSNode(IStructuredDocumentRegion container) {
    if (container == null)
        return;
    ITextRegionCollection containerRegion = container;
    Iterator regions = containerRegion.getRegions().iterator();
    ITextRegion region = null;
    char[] spaces = Util.getPad(container.getStartOffset() - scriptOffset);
    for (int i = 0; i < spaces.length; i++) {
        try {
            char c = fStructuredDocument.getChar(scriptOffset + i);
            if (c == '\n' || c == '\r' || c == '\t')
                spaces[i] = c;
        } catch (BadLocationException e) {
            Logger.logException(e);
        }
    }
    fScriptText.append(spaces);
    scriptOffset = container.getStartOffset();
    if (container.getType() != DOMRegionContext.BLOCK_TEXT && container.getType() != DOMRegionContext.XML_CDATA_TEXT) {
        // add place holder in position map (for formatting)
        appendAndTrack("", scriptOffset);
        return;
    }
    while (regions.hasNext() && !isCanceled()) {
        region = (ITextRegion) regions.next();
        String type = region.getType();
        // content assist was not showing up in JSP inside a javascript
        // region
        // System.out.println("Region text: " + container.getText().substring(region.getStart(), region.getEnd()));
        boolean isContainerRegion = region instanceof ITextRegionContainer;
        /* make sure its not a sub container region, probably JSP */
        if (type == DOMRegionContext.BLOCK_TEXT) {
            int scriptStartOffset = container.getStartOffset(region);
            int scriptTextLength = container.getLength();
            String regionText = container.getFullText(region);
            // regionText = StringUtils.replace(regionText, CDATA_START, CDATA_START_PAD);
            // regionText = StringUtils.replace(regionText, CDATA_END, CDATA_END_PAD);
            int regionLength = region.getLength();
            spaces = Util.getPad(scriptStartOffset - scriptOffset);
            for (int i = 0; i < spaces.length; i++) {
                try {
                    char c = fStructuredDocument.getChar(scriptOffset + i);
                    if (c == '\n' || c == '\r' || c == '\t')
                        spaces[i] = c;
                } catch (BadLocationException e) {
                    Logger.logException(e);
                }
            }
            fScriptText.append(spaces);
            // skip over XML/HTML comment starts
            if (regionText.indexOf(XML_COMMENT_START) >= 0) {
                int index = regionText.indexOf(XML_COMMENT_START);
                boolean replaceCommentStart = true;
                for (int i = 0; i < index; i++) {
                    /*
						 * replace the comment start in the translation when
						 * it's preceded only by white space or '/'
						 */
                    replaceCommentStart = replaceCommentStart && (Character.isWhitespace(regionText.charAt(i)) || '/' == regionText.charAt(i));
                }
                if (replaceCommentStart) {
                    IRegion line;
                    int end;
                    int length;
                    try {
                        /*
							 * try to find where the line with the comment
							 * ends (it is the end of what we'll replace)
							 */
                        line = container.getParentDocument().getLineInformationOfOffset(index + scriptStartOffset);
                        end = line.getOffset() + line.getLength() - scriptStartOffset;
                        if (end > regionText.length()) {
                            end = regionText.length();
                        }
                        length = end - index;
                    } catch (BadLocationException e) {
                        // $NON-NLS-1$
                        Logger.logException("Could not get web page's comment line information", e);
                        end = index + XML_COMMENT_START.length();
                        length = XML_COMMENT_START.length();
                    }
                    scriptStartOffset += end;
                    regionText = regionText.substring(end);
                    appendAndTrack(new String(Util.getPad(end)), fScriptText.length());
                }
            }
            /*
				 * Fix for
				 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=284774
				 * end of last valid JS source, start of next content to
				 * skip
				 */
            // last offset of valid JS source, after which there's server-side stuff
            int validJSend = 0;
            // start of next valid JS source, last offset of content that was skipped
            int validJSstart = 0;
            Matcher matcher = fClientSideTagPattern.matcher(regionText);
            // note the start of a HTML tag if one's present
            int clientMatchStart = matcher.find() ? matcher.start() : -1;
            StringBuffer generatedContent = new StringBuffer();
            int serverSideStart = -1;
            int serverSideDelimiter = 0;
            // find any instance of server code blocks in the region text
            for (int i = 0; i < fServerSideDelimiters.length; i++) {
                int index = regionText.indexOf(fServerSideDelimiters[i][0]);
                if (serverSideStart < 0) {
                    serverSideStart = index;
                    serverSideDelimiter = i;
                } else if (index >= 0) {
                    serverSideStart = Math.min(serverSideStart, index);
                    if (serverSideStart == index) {
                        serverSideDelimiter = i;
                    }
                }
            }
            // contains something other than pure JavaScript
            while (serverSideStart > -1 || clientMatchStart > -1) {
                // $NON-NLS-1$
                validJSend = validJSstart;
                boolean biasClient = false;
                boolean biasServer = false;
                // update the start of content to skip
                if (clientMatchStart > -1 && serverSideStart > -1) {
                    validJSend = Math.min(clientMatchStart, serverSideStart);
                    biasClient = validJSend == clientMatchStart;
                    biasServer = validJSend == serverSideStart;
                } else if (clientMatchStart > -1 && serverSideStart < 0) {
                    validJSend = clientMatchStart;
                    biasClient = true;
                } else if (clientMatchStart < 0 && serverSideStart > -1) {
                    validJSend = serverSideStart;
                    biasServer = true;
                }
                // append if there's something we want to include
                if (-1 < validJSstart && -1 < validJSend) {
                    // append what we want to include
                    appendAndTrack(regionText.substring(validJSstart, validJSend), scriptStartOffset + validJSstart);
                    // change the skipped content to a valid variable name and append it as a placeholder
                    int startOffset = scriptStartOffset + validJSend;
                    String serverEnd = fServerSideDelimiters[serverSideDelimiter][1];
                    int serverSideEnd = (regionLength > validJSend + serverEnd.length()) ? regionText.indexOf(serverEnd, validJSend + fServerSideDelimiters[serverSideDelimiter][1].length()) : -1;
                    if (serverSideEnd > -1)
                        serverSideEnd += serverEnd.length();
                    int clientMatchEnd = matcher.find(validJSend) ? matcher.end() : -1;
                    // update end of what we skipped
                    validJSstart = -1;
                    if (clientMatchEnd > validJSend && serverSideEnd > validJSend) {
                        if (biasClient)
                            validJSstart = clientMatchEnd;
                        else if (biasServer)
                            validJSstart = serverSideEnd;
                        else
                            validJSstart = Math.min(clientMatchEnd, serverSideEnd);
                    }
                    if (clientMatchEnd >= validJSend && serverSideEnd < 0)
                        validJSstart = matcher.end();
                    if (clientMatchEnd < 0 && serverSideEnd >= validJSend)
                        validJSstart = serverSideEnd;
                    /*
						 * the substitution text length much match original
						 * length exactly, generate text of the right length
						 */
                    int start = scriptStartOffset + validJSend;
                    int end = scriptStartOffset + validJSstart;
                    generatedContent.append('_');
                    for (int i = validJSend + 1; i < validJSstart; i++) {
                        switch(i - validJSend) {
                            case 1:
                                generatedContent.append('$');
                                break;
                            case 2:
                                generatedContent.append('t');
                                break;
                            case 3:
                                generatedContent.append('a');
                                break;
                            case 4:
                                generatedContent.append('g');
                                break;
                            default:
                                generatedContent.append('_');
                        }
                    }
                    /*
						 * Remember this source range, it may be needed to
						 * find the original contents for which we're
						 * placeholding
						 */
                    fGeneratedRanges.add(new Region(start, end - start));
                    appendAndTrack(generatedContent.toString(), start);
                    // reset now that it's been appended
                    generatedContent.setLength(0);
                }
                // set up to end while if no end for valid
                if (validJSstart > 0) {
                    int serverSideStartGuess = -1;
                    for (int i = 0; i < fServerSideDelimiters.length; i++) {
                        int index = regionText.indexOf(fServerSideDelimiters[i][0], validJSstart);
                        if (serverSideStartGuess < 0) {
                            serverSideStartGuess = index;
                            serverSideDelimiter = i;
                        } else if (index >= 0) {
                            serverSideStartGuess = Math.min(serverSideStartGuess, index);
                            if (serverSideStartGuess == index) {
                                serverSideDelimiter = i;
                            }
                        }
                    }
                    serverSideStart = validJSstart < regionLength - fShortestServerSideDelimiterPairLength ? serverSideStartGuess : -1;
                    clientMatchStart = validJSstart < regionLength ? (matcher.find(validJSstart) ? matcher.start() : -1) : -1;
                } else {
                    serverSideStart = clientMatchStart = -1;
                }
            }
            if (validJSstart >= 0) {
                appendAndTrack(regionText.substring(validJSstart), scriptStartOffset + validJSstart);
                Position inHtml = new Position(scriptStartOffset + validJSstart, regionText.length() - validJSstart);
                scriptLocationInHtml.add(inHtml);
            } else {
                appendAndTrack(regionText, scriptStartOffset);
                Position inHtml = new Position(scriptStartOffset, regionText.length());
                scriptLocationInHtml.add(inHtml);
            }
            scriptOffset = fScriptText.length();
        }
    }
    IStructuredDocumentRegion endTag = container.getNext();
    if (endTag == null) {
        missingEndTagRegionStart = container.getStartOffset();
    } else if (endTag != null) {
        NodeHelper nh = new NodeHelper(endTag);
        String name = nh.getTagName();
        if (name == null || !name.trim().equalsIgnoreCase("script") || !nh.isEndTag()) {
            // $NON-NLS-1$
            missingEndTagRegionStart = container.getStartOffset();
        }
    }
}
Also used : IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) Matcher(java.util.regex.Matcher) Position(org.eclipse.jface.text.Position) ITextRegionCollection(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection) ITextRegionContainer(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer) IRegion(org.eclipse.jface.text.IRegion) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Iterator(java.util.Iterator) Region(org.eclipse.jface.text.Region) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) IRegion(org.eclipse.jface.text.IRegion) IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) BadLocationException(org.eclipse.jface.text.BadLocationException)

Example 4 with ITextRegionContainer

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer in project webtools.sourceediting by eclipse.

the class JSPELCompletionProposalComputer method computeCompletionProposals.

/**
 * @see org.eclipse.jst.jsp.ui.internal.contentassist.JSPJavaCompletionProposalComputer#computeCompletionProposals(org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
 */
public List computeCompletionProposals(CompletionProposalInvocationContext context, IProgressMonitor monitor) {
    ITextViewer viewer = context.getViewer();
    int documentPosition = context.getInvocationOffset();
    // get results from JSP completion processor
    // 3 for the "get" at the beginning of the java proposal
    List results = new ArrayList(computeJavaCompletionProposals(viewer, documentPosition, 3));
    // get the function proposals for syntax like: ${ fn:| }
    IStructuredDocumentRegion flat = ContentAssistUtils.getStructuredDocumentRegion(viewer, documentPosition);
    if (flat != null) {
        ITextRegion cursorRegion = flat.getRegionAtCharacterOffset(documentPosition);
        String elText;
        int startOffset;
        // else can use flat region
        if (cursorRegion instanceof ITextRegionContainer) {
            ITextRegionContainer container = (ITextRegionContainer) cursorRegion;
            cursorRegion = container.getRegionAtCharacterOffset(documentPosition);
            elText = container.getText(cursorRegion);
            startOffset = container.getStartOffset(cursorRegion);
        } else {
            elText = flat.getText(cursorRegion);
            startOffset = flat.getStartOffset(cursorRegion);
        }
        // sanity check that we are actually in EL region
        if (cursorRegion.getType() == DOMJSPRegionContexts.JSP_EL_CONTENT) {
            String prefix = getPrefix(documentPosition - startOffset, elText);
            if (null != prefix) {
                List proposals = getFunctionProposals(prefix, viewer, documentPosition);
                results.addAll(proposals);
            }
        }
    }
    return results;
}
Also used : IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ITextRegionContainer(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer) ITextViewer(org.eclipse.jface.text.ITextViewer)

Example 5 with ITextRegionContainer

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer in project webtools.sourceediting by eclipse.

the class JSPTranslator method translateRegionContainer.

/**
 * translates a region container (and XML JSP container, or <% JSP
 * container)
 *
 * This method should only be called in this class and for containers in
 * the primary structured document as all buffer appends will be direct
 */
protected void translateRegionContainer(ITextRegionCollection container, int JSPType) {
    ITextRegionCollection containerRegion = container;
    Iterator regions = containerRegion.getRegions().iterator();
    ITextRegion region = null;
    while (regions.hasNext()) {
        region = (ITextRegion) regions.next();
        String type = region.getType();
        // content assist was not showing up in JSP inside a javascript region
        if (DOMRegionContext.BLOCK_TEXT == type) {
            // check if it's nested jsp in a script tag...
            if (region instanceof ITextRegionContainer) {
                // pass in block text's container & iterator
                Iterator regionIterator = ((ITextRegionCollection) region).getRegions().iterator();
                translateJSPNode(region, regionIterator, type, EMBEDDED_JSP);
            } else {
                // be sure to combine all of the text from the block region
                StringBuffer fullText = new StringBuffer(containerRegion.getFullText(region));
                while (regions.hasNext()) {
                    region = (ITextRegion) regions.next();
                    // Do not immediately translate container regions, since they may use variables declared within the full text
                    if (region.getType() == DOMRegionContext.BLOCK_TEXT) {
                        fullText.append(containerRegion.getFullText(region));
                    } else {
                        // update type for when we exit if statement for BLOCK_TEXT
                        type = region.getType();
                        break;
                    }
                }
                /**
                 * LIMITATION - Normally the script content within a
                 * script tag is a single document region with a single
                 * BLOCK_TEXT text region within it. Any JSP scripting
                 * will be within its own region container (for the sake
                 * of keeping the scripting open/content/end as a group)
                 * also of BLOCK_TEXT. That ignores custom tags that might
                 * be in there, though, as they require proper scoping and
                 * variable declaration to be performed even though
                 * they're not proper nodes in the DOM. The only way to
                 * really do this is to treat the entire script content as
                 * JSP content on its own, akin to an included segment.
                 * Further complicating this solution is that tagdependent
                 * custom tags have their comment marked as BLOCK_TEXT as
                 * well, so there's no clear way to tell the two cases
                 * apart.
                 */
                // ////////////////////////////////////////////////////////////////////////////////
                // THIS EMBEDDED JSP TEXT WILL COME OUT LATER WHEN
                // PARTITIONING HAS
                // SUPPORT FOR NESTED XML-JSP
                // CMVC 241882
                decodeScriptBlock(fullText.toString(), containerRegion.getStartOffset());
            // ////////////////////////////////////////////////////////////////////////////////
            }
        }
        // }
        if (// <%, <%=, <%!, <%@
        type != null && isJSP(type)) {
            // translateJSPNode(region, regions, type, JSPType);
            translateJSPNode(containerRegion, regions, type, JSPType);
        } else if (type != null && (type == DOMRegionContext.XML_TAG_OPEN || type == DOMRegionContext.XML_END_TAG_OPEN)) {
            translateXMLNode(containerRegion, regions);
        } else if (type != null && type == DOMRegionContext.XML_CONTENT && region instanceof ITextRegionContainer) {
            // this case was put in to parse EL that is not in an attribute
            translateXMLContent((ITextRegionContainer) region);
        } else // the end tags of these regions are "translated" in a sense
        if (type == DOMJSPRegionContexts.JSP_DIRECTIVE_CLOSE || type == DOMJSPRegionContexts.JSP_CLOSE) {
            this.fCodeTranslated = true;
        }
    }
}
Also used : ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Iterator(java.util.Iterator) ITextRegionCollection(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection) ITextRegionContainer(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer)

Aggregations

ITextRegionContainer (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer)52 ITextRegion (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion)39 IStructuredDocumentRegion (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)26 ITextRegionList (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList)25 IStructuredDocumentRegionList (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList)11 Iterator (java.util.Iterator)10 IDOMNode (org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode)10 List (java.util.List)8 ArrayList (java.util.ArrayList)7 CustomCompletionProposal (org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal)6 ICompletionProposal (org.eclipse.jface.text.contentassist.ICompletionProposal)4 IExtensionPoint (org.eclipse.core.runtime.IExtensionPoint)3 ITextViewer (org.eclipse.jface.text.ITextViewer)3 Image (org.eclipse.swt.graphics.Image)3 IStructuredDocument (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument)3 ITextRegionCollection (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection)3 CMElementDeclaration (org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration)3 CMNamedNodeMap (org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap)3 CMNode (org.eclipse.wst.xml.core.internal.contentmodel.CMNode)3 NamedNodeMap (org.w3c.dom.NamedNodeMap)3