001: package nz.ac.massey.take.takeep.editor;
002:
003: import java.util.ArrayList;
004: import java.util.Iterator;
005:
006: import nz.ac.massey.take.takeep.editor.tokens.TakePartitionScanner.TAKE_PARTITIONS;
007: import nz.ac.massey.take.takeep.outline.TakeOutline;
008:
009: import org.eclipse.jdt.core.util.IAnnotation;
010: import org.eclipse.jface.text.source.IAnnotationHover;
011: import org.eclipse.jface.text.BadLocationException;
012: import org.eclipse.jface.text.IDocument;
013: import org.eclipse.jface.text.IRegion;
014: import org.eclipse.jface.text.ITextHover;
015: import org.eclipse.jface.text.ITextViewer;
016: import org.eclipse.jface.text.Position;
017: import org.eclipse.jface.text.TextAttribute;
018: import org.eclipse.jface.text.presentation.IPresentationReconciler;
019: import org.eclipse.jface.text.presentation.PresentationReconciler;
020: import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
021: import org.eclipse.jface.text.rules.ICharacterScanner;
022: import org.eclipse.jface.text.rules.IRule;
023: import org.eclipse.jface.text.rules.IToken;
024: import org.eclipse.jface.text.rules.IWordDetector;
025: import org.eclipse.jface.text.rules.RuleBasedScanner;
026: import org.eclipse.jface.text.rules.SingleLineRule;
027: import org.eclipse.jface.text.rules.Token;
028: import org.eclipse.jface.text.rules.WordRule;
029: import org.eclipse.jface.text.source.Annotation;
030: import org.eclipse.jface.text.source.IAnnotationModel;
031: import org.eclipse.jface.text.source.ISourceViewer;
032: import org.eclipse.jface.text.source.SourceViewerConfiguration;
033: import org.eclipse.swt.graphics.Color;
034: import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
035:
036: public class TakeSourceViewerConfiguration extends
037: SourceViewerConfiguration {
038:
039: private TakeEditor editor;
040:
041: @Override
042: public IAnnotationHover getAnnotationHover(
043: ISourceViewer sourceViewer) {
044:
045: IAnnotationHover ihover = new IAnnotationHover() {
046:
047: @Override
048: public String getHoverInfo(ISourceViewer sourceViewer,
049: int lineNumber) {
050: IDocument document = sourceViewer.getDocument();
051: ResourceMarkerAnnotationModel annotationModel = (ResourceMarkerAnnotationModel) editor
052: .getDocumentProvider().getAnnotationModel(
053: editor.getEditorInput());
054:
055: Iterator<Annotation> iter = annotationModel
056: .getAnnotationIterator();
057: String message = null;
058: while (iter.hasNext()) {
059: Annotation a = iter.next();
060: Position p = annotationModel.getPosition(a);
061: IRegion i;
062: try {
063: i = document.getLineInformation(lineNumber);
064:
065: if (p
066: .overlapsWith(i.getOffset(), i
067: .getLength())) {
068:
069: if (message == null) {
070: message = a.getText();
071: } else {
072: message += "\n" + a.getText();
073: }
074: }
075: } catch (BadLocationException e) {
076: return null;
077: }
078: return message;
079: }
080: return null;
081:
082: }
083: };
084: return ihover;
085: }
086:
087: @Override
088: public ITextHover getTextHover(ISourceViewer sourceViewer,
089: String contentType, int stateMask) {
090: // TODO Auto-generated method stub
091: return this .getTextHover(sourceViewer, contentType);
092: }
093:
094: @Override
095: public ITextHover getTextHover(ISourceViewer sourceViewer,
096: String contentType) {
097:
098: return new ITextHover() {
099:
100: @Override
101: public String getHoverInfo(ITextViewer textViewer,
102: IRegion hoverRegion) {
103: IDocument document = textViewer.getDocument();
104: ResourceMarkerAnnotationModel annotationModel = (ResourceMarkerAnnotationModel) editor
105: .getDocumentProvider().getAnnotationModel(
106: editor.getEditorInput());
107:
108: Iterator<Annotation> iter = annotationModel
109: .getAnnotationIterator();
110: String message = null;
111: while (iter.hasNext()) {
112: Annotation a = iter.next();
113: Position p = annotationModel.getPosition(a);
114:
115: if (p.overlapsWith(hoverRegion.getOffset(),
116: hoverRegion.getLength())) {
117:
118: if (message == null) {
119: message = a.getText();
120: } else {
121: message += "\n" + a.getText();
122: }
123: }
124:
125: return message;
126: }
127: return null;
128: }
129:
130: @Override
131: public IRegion getHoverRegion(ITextViewer textViewer,
132: int offset) {
133:
134: try {
135: return textViewer.getDocument()
136: .getLineInformationOfOffset(offset);
137: } catch (BadLocationException e) {
138: // TODO Auto-generated catch block
139: e.printStackTrace();
140: return null;
141: }
142:
143: }
144: };
145: }
146:
147: private DesignManager designManager;
148:
149: public enum TAKE_TOKENS {
150: TAKE_KEYWORD, TAKE_STRING_LITERAL
151:
152: }
153:
154: public TakeSourceViewerConfiguration(TakeEditor takeEditor,
155: DesignManager colorManager) {
156: this .editor = takeEditor;
157: this .designManager = colorManager;
158: }
159:
160: @Override
161: public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
162: ArrayList<String> strings = new ArrayList<String>();
163: strings.add(IDocument.DEFAULT_CONTENT_TYPE);
164:
165: for (TAKE_PARTITIONS tp : TAKE_PARTITIONS.values()) {
166: strings.add(tp.name());
167: }
168:
169: for (TAKE_TOKENS tp : TAKE_TOKENS.values()) {
170: strings.add(tp.name());
171: }
172:
173: return strings.toArray(new String[strings.size()]);
174: }
175:
176: class TokenHighlighter extends RuleBasedScanner {
177:
178: public TokenHighlighter(Color c, int style) {
179: setDefaultReturnToken(buildTextAttributeToken(c, style));
180: }
181:
182: }
183:
184: public Token buildTextAttributeToken(Color c, int style) {
185: return new Token(new TextAttribute(c, null, style));
186: }
187:
188: class BodyScanner extends RuleBasedScanner {
189: private String[] keyWords = { "var", "not", "ref", "and", "if",
190: "then", "query", "external", "in", "out",
191: "aggregation", "sum", "max", "min", "avg", "count",
192: "import" };
193:
194: public BodyScanner() {
195: WordRule rule = new WordRule(new IWordDetector() {
196: public boolean isWordStart(char c) {
197: return Character.isJavaIdentifierStart(c);
198: }
199:
200: public boolean isWordPart(char c) {
201: return Character.isJavaIdentifierPart(c);
202: }
203:
204: }) {
205:
206: @Override
207: public IToken evaluate(ICharacterScanner scanner) {
208: scanner.unread();
209: int c = scanner.read();
210: if (Character.isLetterOrDigit(c)) {
211: return Token.UNDEFINED;
212: }
213: return super .evaluate(scanner);
214: }
215:
216: };
217:
218: Token keyword = buildTextAttributeToken(
219: TakeSourceViewerConfiguration.this .designManager
220: .getColor(TAKE_TOKENS.TAKE_KEYWORD.name()),
221: TakeSourceViewerConfiguration.this .designManager
222: .getStyle(TAKE_TOKENS.TAKE_KEYWORD.name()));
223:
224: for (String s : this .keyWords) {
225: rule.addWord(s, keyword);
226: }
227:
228: Token stringLiteral = buildTextAttributeToken(
229: TakeSourceViewerConfiguration.this .designManager
230: .getColor(TAKE_TOKENS.TAKE_STRING_LITERAL
231: .name()),
232: TakeSourceViewerConfiguration.this .designManager
233: .getStyle(TAKE_TOKENS.TAKE_STRING_LITERAL
234: .name()));
235: SingleLineRule stringLiteralRule = new SingleLineRule("\"",
236: "\"", stringLiteral, (char) 0);
237:
238: setRules(new IRule[] { rule, stringLiteralRule });
239: }
240: }
241:
242: @Override
243: public IPresentationReconciler getPresentationReconciler(
244: ISourceViewer sourceViewer) {
245: PresentationReconciler reconciler = new PresentationReconciler();
246:
247: setUpDamageReconciler(reconciler,
248: TAKE_PARTITIONS.TAKE_LOCAL_ANNOTATION.name());
249: setUpDamageReconciler(reconciler,
250: TAKE_PARTITIONS.TAKE_GLOBAL_ANNOTATION.name());
251: setUpDamageReconciler(reconciler, TAKE_PARTITIONS.TAKE_COMMENT
252: .name());
253:
254: setUpDamageReconciler(reconciler,
255: TAKE_TOKENS.TAKE_STRING_LITERAL.name());
256:
257: DefaultDamagerRepairer bodyDR = new DefaultDamagerRepairer(
258: new BodyScanner());
259:
260: setKeywordHighlightingPartition(reconciler, bodyDR,
261: IDocument.DEFAULT_CONTENT_TYPE);
262: setKeywordHighlightingPartition(reconciler, bodyDR,
263: TAKE_PARTITIONS.TAKE_EXTERNAL.name());
264: setKeywordHighlightingPartition(reconciler, bodyDR,
265: TAKE_PARTITIONS.TAKE_QUERY.name());
266: setKeywordHighlightingPartition(reconciler, bodyDR,
267: TAKE_PARTITIONS.TAKE_RULE_OR_FACT.name());
268: setKeywordHighlightingPartition(reconciler, bodyDR,
269: TAKE_PARTITIONS.TAKE_REF.name());
270: setKeywordHighlightingPartition(reconciler, bodyDR,
271: TAKE_PARTITIONS.TAKE_VAR.name());
272: setKeywordHighlightingPartition(reconciler, bodyDR,
273: TAKE_PARTITIONS.TAKE_AGGREGATION.name());
274: setKeywordHighlightingPartition(reconciler, bodyDR,
275: TAKE_PARTITIONS.TAKE_IMPORT.name());
276:
277: return reconciler;
278: }
279:
280: private void setKeywordHighlightingPartition(
281: PresentationReconciler reconciler,
282: DefaultDamagerRepairer dr, String type) {
283: reconciler.setDamager(dr, type);
284: reconciler.setRepairer(dr, type);
285: }
286:
287: private void setUpDamageReconciler(
288: PresentationReconciler reconciler, String tokenValue) {
289: DefaultDamagerRepairer dr = new DefaultDamagerRepairer(
290: buildTokenDesign(tokenValue));
291: setKeywordHighlightingPartition(reconciler, dr, tokenValue);
292: }
293:
294: private TokenHighlighter buildTokenDesign(String tokenValue) {
295: Integer style = this .designManager.getStyle(tokenValue);
296: Color color = this .designManager.getColor(tokenValue);
297:
298: return new TokenHighlighter(color, style);
299:
300: }
301: }
|