001: /*******************************************************************************
002: * Copyright (c) 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.contentassist;
011:
012: import org.eclipse.jface.text.BadLocationException;
013: import org.eclipse.jface.text.IDocument;
014:
015: /**
016: * Content assist text is any contiguous segment of text that can be
017: * construed as the beginning of a element document node prior to invoking
018: * content assist at the end of it.
019: */
020: public class XMLContentAssistText {
021:
022: private String fText;
023:
024: private int fStartOffset;
025:
026: private XMLContentAssistText(String text, int startOffset) {
027: fText = text;
028: fStartOffset = startOffset;
029: }
030:
031: /**
032: * Parses document for content assist text.
033: * @param offset The document offset to start scanning backward from
034: * @param document The document
035: * @return new content assist text if found; otherwise, returns null.
036: */
037: public static XMLContentAssistText parse(int offset,
038: IDocument document) {
039: boolean writeCAText = true;
040: int lastCATextOffset = -1;
041: StringBuffer buffer = new StringBuffer();
042: int endOffset = offset - 1;
043: char currentChar;
044:
045: if (offset <= 0) {
046: return null;
047: }
048: // Performance enhancement
049: // Ensure the first character is valid content assist text
050: try {
051: currentChar = document.getChar(endOffset);
052: } catch (BadLocationException e) {
053: return null;
054: }
055: if (isContentAssistText(currentChar)) {
056: buffer.append(currentChar);
057: lastCATextOffset = endOffset;
058: } else {
059: return null;
060: }
061: // Scan backwards from specified offset until we find a right angle
062: // bracket
063: for (int i = endOffset - 1; i > 0; i--) {
064: try {
065: currentChar = document.getChar(i);
066: } catch (BadLocationException e) {
067: return null;
068: }
069: if (isContentAssistText(currentChar)) {
070: if (writeCAText) {
071: // Accumulate the contiguous segment of content assist
072: // text
073: buffer.append(currentChar);
074: // Track the start offset of the contiguous segment of
075: // content assist text
076: lastCATextOffset = i;
077: }
078: } else if (Character.isWhitespace(currentChar)) {
079: // We found whitespace. This represents the contiguous text
080: // boundary. Do not write anything else to the buffer.
081: // Continue scanning backwards to make sure we find a right
082: // angle bracket to validate what we have in the buffer is
083: // indeed valid content assist text
084: writeCAText = false;
085: } else if (currentChar == '>') {
086: // We found the right angle bracket, if there is anything in
087: // the buffer it is valid content assist text
088: if (buffer.length() > 0) {
089: return new XMLContentAssistText(buffer.reverse()
090: .toString(), lastCATextOffset);
091: }
092: return null;
093: } else {
094: // We found an invalid content assist character
095: // Anything we have in the buffer is garbage
096: return null;
097: }
098: }
099: // We should never reach here
100: return null;
101: }
102:
103: /**
104: * Determines whether a character is a valid XML element name character
105: * @param c A character
106: * @return True if the character is valid content assist text; Otherwise,
107: * returns false.
108: */
109: private static boolean isContentAssistText(char c) {
110: if ((Character.isLetterOrDigit(c)) || (c == '.') || (c == '-')
111: || (c == '_') || (c == ':')) {
112: return true;
113: }
114: return false;
115: }
116:
117: /**
118: * @return the fText
119: */
120: public String getText() {
121: return fText;
122: }
123:
124: /**
125: * @return the fStartOffset
126: */
127: public int getStartOffset() {
128: return fStartOffset;
129: }
130:
131: /* (non-Javadoc)
132: * @see java.lang.Object#toString()
133: */
134: public String toString() {
135: return "Start Offset: " + fStartOffset + " Text: |" + fText + "|\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
136: }
137: }
|