KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > template > contentassist > SurroundWithTemplateProposal


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.text.template.contentassist;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.Map JavaDoc;
16
17 import org.eclipse.text.edits.MalformedTreeException;
18
19 import org.eclipse.core.runtime.CoreException;
20
21 import org.eclipse.swt.graphics.Image;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.widgets.Shell;
24
25 import org.eclipse.jface.dialogs.MessageDialog;
26
27 import org.eclipse.jface.text.BadLocationException;
28 import org.eclipse.jface.text.Document;
29 import org.eclipse.jface.text.DocumentEvent;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.jface.text.IRegion;
32 import org.eclipse.jface.text.IRewriteTarget;
33 import org.eclipse.jface.text.ITextViewer;
34 import org.eclipse.jface.text.ITextViewerExtension;
35 import org.eclipse.jface.text.Region;
36 import org.eclipse.jface.text.templates.GlobalTemplateVariables;
37 import org.eclipse.jface.text.templates.Template;
38 import org.eclipse.jface.text.templates.TemplateBuffer;
39 import org.eclipse.jface.text.templates.TemplateException;
40
41 import org.eclipse.jdt.core.ICompilationUnit;
42 import org.eclipse.jdt.core.IJavaProject;
43 import org.eclipse.jdt.core.dom.AST;
44 import org.eclipse.jdt.core.dom.ASTNode;
45 import org.eclipse.jdt.core.dom.ASTParser;
46 import org.eclipse.jdt.core.dom.Block;
47 import org.eclipse.jdt.core.dom.MethodDeclaration;
48 import org.eclipse.jdt.core.dom.Statement;
49
50 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
51 import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
52 import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext;
53 import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType;
54 import org.eclipse.jdt.internal.corext.template.java.JavaContextType;
55
56 import org.eclipse.jdt.ui.text.java.IInvocationContext;
57
58 import org.eclipse.jdt.internal.ui.JavaPlugin;
59 import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
60 import org.eclipse.jdt.internal.ui.text.correction.SurroundWith;
61
62 public class SurroundWithTemplateProposal extends TemplateProposal {
63     
64     private static class SurroundWithTemplate extends SurroundWith {
65         
66         private static final String JavaDoc $_LINE_SELECTION= "${" + GlobalTemplateVariables.LineSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
67

68         private final Template fTemplate;
69         private final IJavaProject fCurrentProject;
70         private ASTNode fTemplateNode;
71         
72         public SurroundWithTemplate(IInvocationContext context, Statement[] selectedNodes, Template template) {
73             super(context.getASTRoot(), selectedNodes);
74             fTemplate= template;
75             fCurrentProject= context.getCompilationUnit().getJavaProject();
76         }
77         
78         protected List JavaDoc getVariableDeclarationReadsInside(Statement[] selectedNodes, int maxVariableId) {
79             if (isNewContext())
80                 return super.getVariableDeclarationReadsInside(selectedNodes, maxVariableId);
81             return new ArrayList JavaDoc();
82         }
83         
84         protected boolean isNewContext() {
85
86             final String JavaDoc templateVariableRegEx= "\\$\\{[^\\}]*\\}"; //$NON-NLS-1$
87

88             String JavaDoc template= fTemplate.getPattern();
89             int currentPosition= template.indexOf($_LINE_SELECTION);
90             int insertionPosition= -1;
91             while (currentPosition != -1) {
92                 insertionPosition= currentPosition;
93                 template= template.replaceFirst(templateVariableRegEx, ""); //$NON-NLS-1$
94
currentPosition= template.indexOf($_LINE_SELECTION);
95             }
96             template= template.replaceAll(templateVariableRegEx, ""); //$NON-NLS-1$
97

98             AST ast= getAst();
99             ASTParser parser= ASTParser.newParser(ast.apiLevel());
100             parser.setSource(template.toCharArray());
101             parser.setProject(fCurrentProject);
102             parser.setKind(ASTParser.K_STATEMENTS);
103             ASTNode root= parser.createAST(null);
104             if (((Block)root).statements().isEmpty()) {
105                 parser= ASTParser.newParser(ast.apiLevel());
106                 parser.setSource(template.toCharArray());
107                 parser.setProject(fCurrentProject);
108                 parser.setKind(ASTParser.K_EXPRESSION);
109                 root= parser.createAST(null);
110             }
111             
112             final int lineSelectionPosition= insertionPosition;
113             root.accept(new GenericVisitor() {
114                 public void endVisit(Block node) {
115                     super.endVisit(node);
116                     if (fTemplateNode == null && node.getStartPosition() <= lineSelectionPosition && node.getLength() + node.getStartPosition() >= lineSelectionPosition) {
117                         fTemplateNode= node;
118                     }
119                 }
120             });
121             
122             if (fTemplateNode != null && ASTNodes.getParent(fTemplateNode, MethodDeclaration.class) != null) {
123                 return true;
124             }
125             
126             return false;
127         }
128         
129     }
130
131
132     private final IRegion fRegion;
133     private final ICompilationUnit fCompilationUnit;
134     private final CompilationUnitContext fContext;
135     private final Template fTemplate;
136     private final Statement[] fSelectedStatements;
137     private TemplateProposal fProposal;
138     private IRegion fSelectedRegion;
139
140     public SurroundWithTemplateProposal(ICompilationUnit compilationUnit, Template template, CompilationUnitContext context, IRegion region, Image image, Statement[] selectedStatements) {
141         super(template, context, region, image);
142         fCompilationUnit= compilationUnit;
143         fTemplate= template;
144         fContext= context;
145         fRegion= region;
146         fSelectedStatements= selectedStatements;
147     }
148     
149     /* (non-Javadoc)
150      * @see org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal#getAdditionalProposalInfo()
151      */

152     public String JavaDoc getPreviewContent() {
153         try {
154             IDocument document= new Document(fCompilationUnit.getBuffer().getContents());
155             CompilationUnitContext context= createNewContext(document);
156             
157             int offset= context.getCompletionOffset();
158             int start= context.getStart();
159             int end= context.getEnd();
160             IRegion region= new Region(start, end - start);
161             
162             context.setReadOnly(false);
163             TemplateBuffer templateBuffer;
164             try {
165                 templateBuffer= context.evaluate(fTemplate);
166             } catch (TemplateException e1) {
167                 JavaPlugin.log(e1);
168                 return null;
169             }
170             
171             start= region.getOffset();
172             end= region.getOffset() + region.getLength();
173             end= Math.max(end, offset);
174
175             String JavaDoc templateString= templateBuffer.getString();
176             document.replace(start, end - start, templateString);
177             
178             return document.get();
179             
180         } catch (MalformedTreeException e) {
181             JavaPlugin.log(e);
182         } catch (IllegalArgumentException JavaDoc e) {
183             JavaPlugin.log(e);
184         } catch (BadLocationException e) {
185             JavaPlugin.log(e);
186         } catch (CoreException e) {
187             JavaPlugin.log(e);
188         }
189         return null;
190     }
191
192     /* (non-Javadoc)
193      * @see org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal#apply(org.eclipse.jface.text.ITextViewer, char, int, int)
194      */

195     public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
196         try {
197             setRedraw(viewer, false);
198             IDocument document= viewer.getDocument();
199             CompilationUnitContext context= createNewContext(document);
200             
201             int start= context.getStart();
202             int end= context.getEnd();
203             IRegion region= new Region(start, end - start);
204
205             //Evaluate the template within the new context
206
fProposal= new TemplateProposal(fTemplate, context, region, null);
207             fProposal.apply(viewer, trigger, stateMask, context.getCompletionOffset());
208         } catch (MalformedTreeException e) {
209             handleException(viewer, e, fRegion);
210         } catch (IllegalArgumentException JavaDoc e) {
211             handleException(viewer, e, fRegion);
212         } catch (BadLocationException e) {
213             handleException(viewer, e, fRegion);
214         } catch (CoreException e) {
215             handleException(viewer, e, fRegion);
216         } finally {
217             setRedraw(viewer, true);
218         }
219     }
220     
221     private void setRedraw(ITextViewer viewer, boolean redraw) {
222         if (viewer instanceof ITextViewerExtension) {
223             ITextViewerExtension extension= (ITextViewerExtension) viewer;
224             IRewriteTarget target= extension.getRewriteTarget();
225             target.setRedraw(redraw);
226         }
227     }
228
229     public Point getSelection(IDocument document) {
230         if (fSelectedRegion != null) {
231             return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength());
232         } else if (fProposal != null) {
233             return fProposal.getSelection(document);
234         } else {
235             return null;
236         }
237     }
238     
239     private CompilationUnitContext createNewContext(IDocument document) throws CoreException, BadLocationException {
240         AssistContext invocationContext= new AssistContext(fCompilationUnit, fContext.getStart(), fContext.getEnd() - fContext.getStart());
241         
242         SurroundWithTemplate surroundWith= new SurroundWithTemplate(invocationContext, fSelectedStatements, fTemplate);
243         Map JavaDoc options= fCompilationUnit.getJavaProject().getOptions(true);
244         
245         surroundWith.getRewrite().rewriteAST(document, options).apply(document);
246         
247         int offset= surroundWith.getBodyStart();
248         int length= surroundWith.getBodyLength();
249         String JavaDoc newSelection= document.get(offset, length);
250         
251         //Create the new context
252
CompilationUnitContextType contextType= (CompilationUnitContextType) JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(JavaContextType.NAME);
253         CompilationUnitContext context= contextType.createContext(document, offset, newSelection.length(), fCompilationUnit);
254         context.setVariable("selection", newSelection); //$NON-NLS-1$
255
context.setForceEvaluation(true);
256         return context;
257     }
258     
259     private void handleException(ITextViewer viewer, Exception JavaDoc e, IRegion region) {
260         JavaPlugin.log(e);
261         openErrorDialog(viewer.getTextWidget().getShell(), e);
262         fSelectedRegion= region;
263     }
264
265     private void openErrorDialog(Shell shell, Exception JavaDoc e) {
266         MessageDialog.openError(shell, TemplateContentAssistMessages.TemplateEvaluator_error_title, e.getMessage());
267     }
268     
269     /**
270      * {@inheritDoc}
271      */

272     public boolean validate(IDocument document, int offset, DocumentEvent event) {
273         return false;
274     }
275 }
276
Popular Tags