001: /*******************************************************************************
002: * Copyright (c) 2000, 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.jdt.internal.ui.text.template.preferences;
011:
012: import java.util.ArrayList;
013: import java.util.Collections;
014: import java.util.Comparator;
015: import java.util.Iterator;
016: import java.util.List;
017:
018: import org.eclipse.jface.text.ITextViewer;
019: import org.eclipse.jface.text.contentassist.ICompletionProposal;
020: import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
021: import org.eclipse.jface.text.contentassist.IContextInformation;
022: import org.eclipse.jface.text.contentassist.IContextInformationValidator;
023: import org.eclipse.jface.text.templates.TemplateContextType;
024: import org.eclipse.jface.text.templates.TemplateVariableResolver;
025:
026: public class TemplateVariableProcessor implements
027: IContentAssistProcessor {
028:
029: private static Comparator fgTemplateVariableProposalComparator = new Comparator() {
030: public int compare(Object arg0, Object arg1) {
031: TemplateVariableProposal proposal0 = (TemplateVariableProposal) arg0;
032: TemplateVariableProposal proposal1 = (TemplateVariableProposal) arg1;
033:
034: return proposal0.getDisplayString().compareTo(
035: proposal1.getDisplayString());
036: }
037:
038: public boolean equals(Object arg0) {
039: return false;
040: }
041: };
042:
043: /** the context type */
044: private TemplateContextType fContextType;
045:
046: /**
047: * Sets the context type.
048: */
049: public void setContextType(TemplateContextType contextType) {
050: fContextType = contextType;
051: }
052:
053: /**
054: * Gets the context type.
055: */
056: public TemplateContextType getContextType() {
057: return fContextType;
058: }
059:
060: /*
061: * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
062: */
063: public ICompletionProposal[] computeCompletionProposals(
064: ITextViewer viewer, int documentOffset) {
065:
066: if (fContextType == null)
067: return null;
068:
069: List proposals = new ArrayList();
070:
071: String text = viewer.getDocument().get();
072: int start = getStart(text, documentOffset);
073: int end = documentOffset;
074:
075: String string = text.substring(start, end);
076: int colon = string.indexOf(':');
077: boolean includeBrace = true;
078: int offset = start;
079: String prefix = string;
080: if (colon != -1) {
081: includeBrace = false;
082: offset = start + colon + 1;
083: prefix = string.substring(colon + 1);
084: } else {
085: int escape = string.indexOf("${"); //$NON-NLS-1$
086: if (escape != -1) {
087: offset = start + escape + 2;
088: includeBrace = false;
089: prefix = string.substring(escape + 2);
090: }
091: }
092: if (prefix.equals("$")) //$NON-NLS-1$
093: prefix = ""; //$NON-NLS-1$
094:
095: int length = end - offset;
096:
097: for (Iterator iterator = fContextType.resolvers(); iterator
098: .hasNext();) {
099: TemplateVariableResolver variable = (TemplateVariableResolver) iterator
100: .next();
101:
102: if (variable.getType().startsWith(prefix))
103: proposals.add(new TemplateVariableProposal(variable,
104: offset, length, viewer, includeBrace));
105: }
106:
107: Collections.sort(proposals,
108: fgTemplateVariableProposalComparator);
109: return (ICompletionProposal[]) proposals
110: .toArray(new ICompletionProposal[proposals.size()]);
111: }
112:
113: /* Guesses the start position of the completion */
114: private int getStart(String string, int end) {
115: int start = end;
116:
117: if (start >= 1 && string.charAt(start - 1) == '$')
118: return start - 1;
119:
120: while ((start != 0)
121: && Character.isUnicodeIdentifierPart(string
122: .charAt(start - 1)))
123: start--;
124:
125: if (start >= 1 && string.charAt(start - 1) == ':') {
126: start--;
127: while ((start != 0)
128: && Character.isUnicodeIdentifierPart(string
129: .charAt(start - 1)))
130: start--;
131: }
132:
133: if (start >= 2 && string.charAt(start - 1) == '{'
134: && string.charAt(start - 2) == '$')
135: return start - 2;
136:
137: return end;
138: }
139:
140: /*
141: * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
142: */
143: public IContextInformation[] computeContextInformation(
144: ITextViewer viewer, int documentOffset) {
145: return null;
146: }
147:
148: /*
149: * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
150: */
151: public char[] getCompletionProposalAutoActivationCharacters() {
152: return new char[] { '$' };
153: }
154:
155: /*
156: * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
157: */
158: public char[] getContextInformationAutoActivationCharacters() {
159: return null;
160: }
161:
162: /*
163: * @see IContentAssistProcessor#getErrorMessage()
164: */
165: public String getErrorMessage() {
166: return null;
167: }
168:
169: /*
170: * @see IContentAssistProcessor#getContextInformationValidator()
171: */
172: public IContextInformationValidator getContextInformationValidator() {
173: return null;
174: }
175:
176: }
|