1 19 20 package org.netbeans.modules.web.core.syntax.completion; 21 import java.io.IOException ; 22 import java.util.List ; 23 import java.util.logging.Level ; 24 import java.util.logging.Logger ; 25 import javax.swing.text.BadLocationException ; 26 import javax.swing.text.Document ; 27 import javax.swing.text.JTextComponent ; 28 import org.netbeans.api.java.source.JavaSource; 29 import org.netbeans.api.jsp.lexer.JspTokenId; 30 import org.netbeans.api.lexer.TokenHierarchy; 31 import org.netbeans.api.lexer.TokenSequence; 32 import org.netbeans.editor.Utilities; 33 import org.netbeans.modules.editor.java.JavaCompletionProvider; 34 import org.netbeans.modules.web.core.syntax.SimplifiedJSPServlet; 35 import org.netbeans.spi.editor.completion.CompletionItem; 36 import org.netbeans.spi.editor.completion.CompletionProvider; 37 import org.netbeans.spi.editor.completion.CompletionResultSet; 38 import org.netbeans.spi.editor.completion.CompletionTask; 39 import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery; 40 import org.netbeans.spi.editor.completion.support.AsyncCompletionTask; 41 import org.openide.filesystems.FileObject; 42 43 51 public class JavaJSPCompletionProvider implements CompletionProvider { 52 private final JavaCompletionProvider javaCompletionProvider = new JavaCompletionProvider(); 53 private static final Logger logger = Logger.getLogger(JavaJSPCompletionProvider.class.getName()); 54 55 public CompletionTask createTask(int queryType, final JTextComponent component) { 56 if ((queryType & COMPLETION_QUERY_TYPE) != 0){ 57 Document doc = Utilities.getDocument(component); 58 int caretOffset = component.getCaret().getDot(); 59 60 if (isWithinScriptlet(doc, caretOffset)){ 61 return new AsyncCompletionTask(new EmbeddedJavaCompletionQuery(component, queryType), component); 63 } 64 } 65 66 return null; 67 } 68 69 private boolean isWithinScriptlet(Document doc, int offset){ 70 TokenHierarchy tokenHierarchy = TokenHierarchy.get(doc); 71 TokenSequence tokenSequence = tokenHierarchy.tokenSequence(); 72 73 tokenSequence.move(offset); 74 if (tokenSequence.moveNext() || tokenSequence.movePrevious()) { 75 Object tokenID = tokenSequence.token().id(); 76 if (tokenID == JspTokenId.SCRIPTLET){ 77 return true; 78 } else if (tokenID == JspTokenId.SYMBOL2) { 79 tokenSequence.movePrevious(); 81 82 if (tokenSequence.token().id() == JspTokenId.SCRIPTLET){ 83 return true; 84 } 85 } 86 } 87 88 return false; 89 } 90 91 public int getAutoQueryTypes(JTextComponent component, String typedText) { 92 return javaCompletionProvider.getAutoQueryTypes(component, typedText); 93 } 94 95 96 static class EmbeddedJavaCompletionQuery extends AsyncCompletionQuery { 97 protected int queryType; 98 protected JTextComponent component; 99 100 public EmbeddedJavaCompletionQuery(JTextComponent component, int queryType){ 101 this.queryType = queryType; 102 this.component = component; 103 } 104 105 protected void query(CompletionResultSet resultSet, Document doc, 106 int caretOffset) { 107 108 SimplifiedJSPServlet simplifiedJSPServlet = new SimplifiedJSPServlet(doc); 109 try{ 110 simplifiedJSPServlet.process(); 111 String fakedClassBody = simplifiedJSPServlet.getVirtualClassBody(); 112 int shiftedOffset = simplifiedJSPServlet.getShiftedOffset(caretOffset); 113 114 if (shiftedOffset >= 0){ 115 logger.fine("JSP CC: delegating CC query to java file:\n" + fakedClassBody.substring(0, shiftedOffset) 117 + "|" + fakedClassBody.substring(shiftedOffset) + "\n"); 119 CompletionQueryDelegatedToJava delegate = new CompletionQueryDelegatedToJava( 120 caretOffset, shiftedOffset, queryType); 121 122 delegate.create(doc, fakedClassBody); 123 List <? extends CompletionItem> items = delegate.getCompletionItems(); 124 resultSet.addAllItems(items); 125 } else{ 126 logger.severe("caretOffset outside of embedded java code"); } 128 } catch (BadLocationException e){ 129 logger.log(Level.SEVERE, e.getMessage(), e); 130 } finally{ 131 resultSet.finish(); 132 } 133 } 134 } 135 136 static class CompletionQueryDelegatedToJava extends SimplifiedJSPServlet.VirtualJavaClass{ 137 private int caretOffset; 138 private int queryType; 139 private int shiftedOffset; 140 private List <? extends CompletionItem> completionItems; 141 142 CompletionQueryDelegatedToJava(int caretOffset, int shiftedOffset, int queryType){ 143 this.caretOffset = caretOffset; 144 this.shiftedOffset = shiftedOffset; 145 this.queryType = queryType; 146 } 147 148 protected void process(FileObject fileObject, JavaSource javaSource){ 149 try{ 150 completionItems = JavaCompletionProvider.query( 151 javaSource, queryType, shiftedOffset, caretOffset); 152 } catch (IOException e){ 153 logger.log(Level.SEVERE, e.getMessage(), e); 154 } 155 } 156 157 List <? extends CompletionItem> getCompletionItems(){ 158 return completionItems; 159 } 160 } 161 162 } 163 164 | Popular Tags |