|
1 | | -import com.google.gson.Gson; |
2 | | -import com.intellij.codeInsight.intention.impl.QuickEditAction; |
3 | | -import com.intellij.notification.Notification; |
4 | | -import com.intellij.notification.NotificationType; |
5 | | -import com.intellij.notification.Notifications; |
| 1 | +import com.intellij.facet.Facet; |
| 2 | +import com.intellij.facet.FacetManager; |
| 3 | +import com.intellij.openapi.actionSystem.AnAction; |
| 4 | +import com.intellij.openapi.actionSystem.AnActionEvent; |
| 5 | +import com.intellij.openapi.actionSystem.DataKeys; |
6 | 6 | import com.intellij.openapi.application.ApplicationManager; |
7 | 7 | import com.intellij.openapi.command.CommandProcessor; |
8 | | -import com.intellij.openapi.command.UndoConfirmationPolicy; |
9 | 8 | import com.intellij.openapi.editor.Document; |
10 | | -import com.intellij.openapi.editor.Editor; |
11 | 9 | import com.intellij.openapi.fileEditor.FileDocumentManager; |
| 10 | +import com.intellij.openapi.module.Module; |
| 11 | +import com.intellij.openapi.module.ModuleManager; |
12 | 12 | import com.intellij.openapi.project.Project; |
13 | | -import com.intellij.openapi.util.Iconable; |
14 | | -import com.intellij.openapi.util.TextRange; |
15 | | -import com.intellij.openapi.vfs.ReadonlyStatusHandler; |
16 | 13 | import com.intellij.openapi.vfs.VirtualFile; |
17 | | -import com.intellij.psi.PsiClass; |
| 14 | +import com.intellij.psi.PsiDocumentManager; |
18 | 15 | import com.intellij.psi.PsiFile; |
19 | | -import com.intellij.psi.PsiFileFactory; |
20 | 16 | import com.intellij.psi.PsiJavaFile; |
21 | | -import com.intellij.psi.codeStyle.CodeStyleManager; |
22 | | -import com.intellij.util.IncorrectOperationException; |
23 | | -import org.apache.http.client.utils.URIBuilder; |
24 | 17 | import org.jetbrains.annotations.NotNull; |
| 18 | +import org.jetbrains.annotations.Nullable; |
25 | 19 |
|
26 | | -import javax.swing.*; |
27 | | -import java.io.BufferedReader; |
28 | | -import java.io.IOException; |
29 | | -import java.io.InputStreamReader; |
30 | | -import java.net.MalformedURLException; |
31 | | -import java.net.URISyntaxException; |
32 | | -import java.net.URL; |
33 | | -import java.net.URLConnection; |
34 | | -import java.util.ArrayList; |
35 | | -import java.util.List; |
36 | | -import java.util.Scanner; |
| 20 | +import java.util.Objects; |
37 | 21 |
|
38 | | - |
39 | | -public class UpdateServiceStackReference extends QuickEditAction implements Iconable { |
| 22 | +/** |
| 23 | + * Created by Layoric on 9/04/2015. |
| 24 | + */ |
| 25 | +public class UpdateServiceStackReference extends AnAction { |
40 | 26 |
|
41 | 27 | @Override |
42 | | - public String getText() { |
43 | | - return "Update ServiceStack reference"; |
| 28 | + public void actionPerformed(AnActionEvent anActionEvent) { |
| 29 | + final PsiJavaFile psiJavaFile = getPsiFile(anActionEvent); |
| 30 | + if(UpdateServiceStackUtils.containsOptionsHeader(psiJavaFile)) { |
| 31 | + ApplicationManager.getApplication().runWriteAction(new Runnable() { |
| 32 | + @Override |
| 33 | + public void run() { |
| 34 | + UpdateServiceStackUtils.updateServiceStackReference(psiJavaFile); |
| 35 | + } |
| 36 | + }); |
| 37 | + } |
44 | 38 | } |
45 | 39 |
|
46 | 40 | @Override |
47 | | - public String getFamilyName() { |
48 | | - return "UpdateServiceStackReference"; |
49 | | - } |
| 41 | + public void update(AnActionEvent e) { |
| 42 | + Module module = getModule(e); |
| 43 | + PsiJavaFile psiJavaFile = getPsiFile(e); |
| 44 | + if (psiJavaFile == null || !isAndroidProject(module)) { |
| 45 | + e.getPresentation().setVisible(false); |
| 46 | + return; |
| 47 | + } |
50 | 48 |
|
51 | | - @Override |
52 | | - public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile psiFile) { |
53 | | - try { |
54 | | - if(psiFile == null || !(psiFile instanceof PsiJavaFile)) { |
55 | | - return false; |
56 | | - } |
57 | | - PsiJavaFile classFile = (PsiJavaFile)psiFile; |
58 | | - if(containsOptionsHeader(classFile)) { |
59 | | - return true; |
60 | | - } |
61 | | - } catch (Exception e) { |
62 | | - e.printStackTrace(); |
| 49 | + if(!UpdateServiceStackUtils.containsOptionsHeader(psiJavaFile)) { |
| 50 | + e.getPresentation().setVisible(false); |
| 51 | + return; |
63 | 52 | } |
64 | | - return false; |
| 53 | + e.getPresentation().setVisible(true); |
| 54 | + super.update(e); |
65 | 55 | } |
66 | 56 |
|
67 | | - private boolean containsOptionsHeader(PsiJavaFile psiJavaFile) { |
68 | | - Document dtoDocument = FileDocumentManager.getInstance().getDocument(psiJavaFile.getVirtualFile()); |
69 | | - if(dtoDocument == null) { |
70 | | - return false; |
| 57 | + static Module getModule(Project project) { |
| 58 | + if (project == null) |
| 59 | + return null; |
| 60 | + Module[] modules = ModuleManager.getInstance(project).getModules(); |
| 61 | + if (modules.length > 0) { |
| 62 | + return modules[0]; |
71 | 63 | } |
72 | | - //Only pull in the first 1000 chars max to look for header. |
73 | | - int range = dtoDocument.getTextLength() > 1000 ? 1000 : dtoDocument.getTextLength(); |
74 | | - String code = dtoDocument.getText(new TextRange(0,range)); |
| 64 | + return null; |
| 65 | + } |
75 | 66 |
|
76 | | - String[] codeLines = code.split("\n"); |
77 | | - for(String line : codeLines) { |
78 | | - if(line.startsWith("BaseUrl:")) { |
| 67 | + private static boolean isAndroidProject(@NotNull Module module) { |
| 68 | + Facet[] facetsByType = FacetManager.getInstance(module).getAllFacets(); |
| 69 | + for (Facet facet :facetsByType) { |
| 70 | + if(Objects.equals(facet.getTypeId().toString(), "android")) { |
79 | 71 | return true; |
80 | 72 | } |
81 | 73 | } |
82 | 74 | return false; |
83 | 75 | } |
84 | 76 |
|
85 | | - private boolean validateEndPoint(String url) { |
| 77 | + private static PsiJavaFile getPsiFile(AnActionEvent e) { |
86 | 78 |
|
87 | | - URL metadataUrl = null; |
88 | | - URIBuilder builder = null; |
89 | | - try { |
90 | | - builder = new URIBuilder(url.replace("types/java","types/metadata")); |
91 | | - builder.addParameter("format","json"); |
92 | | - metadataUrl = new URL(builder.build().toString()); |
93 | | - } catch (URISyntaxException e) { |
94 | | - //Log error to IDEA warning bubble/window. |
95 | | - e.printStackTrace(); |
96 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", "Invalid BaseUrl provided", NotificationType.ERROR); |
97 | | - Notifications.Bus.notify(notification); |
98 | | - return false; |
99 | | - } catch (MalformedURLException e) { |
100 | | - e.printStackTrace(); |
101 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", "Invalid BaseUrl provided", NotificationType.ERROR); |
102 | | - Notifications.Bus.notify(notification); |
103 | | - return false; |
| 79 | + Module module = getModule(e); |
| 80 | + if(module == null) { |
| 81 | + return null; |
104 | 82 | } |
105 | | - |
106 | | - URLConnection metadataConnection = null; |
107 | | - String errorMessage = null; |
108 | | - try { |
109 | | - metadataConnection = metadataUrl.openConnection(); |
110 | | - } catch (IOException e) { |
111 | | - errorMessage = "Problem connecting to BaseUrl - " + e.getMessage(); |
| 83 | + VirtualFile selectedFile = DataKeys.VIRTUAL_FILE.getData(e.getDataContext()); |
| 84 | + if(selectedFile == null) { |
| 85 | + return null; |
112 | 86 | } |
113 | | - metadataConnection.setRequestProperty("content-type", "application/json; charset=utf-8"); |
114 | | - BufferedReader metadataBufferReader = null; |
115 | | - try { |
116 | | - metadataBufferReader = new BufferedReader( |
117 | | - new InputStreamReader( |
118 | | - metadataConnection.getInputStream())); |
119 | | - } catch (IOException e) { |
120 | | - errorMessage = "Problem connecting to BaseUrl - " + e.getMessage(); |
| 87 | + Document document = FileDocumentManager.getInstance().getDocument(selectedFile); |
| 88 | + if(document == null) { |
| 89 | + return null; |
121 | 90 | } |
122 | | - String metadataInputLine; |
123 | | - StringBuilder metadataResponse = new StringBuilder(); |
124 | | - try { |
125 | | - while ((metadataInputLine = metadataBufferReader.readLine()) != null) |
126 | | - metadataResponse.append(metadataInputLine); |
127 | 91 |
|
128 | | - metadataBufferReader.close(); |
129 | | - } catch (IOException e) { |
130 | | - errorMessage = "Invalid response, check the BaseUrl is a valid ServiceStack endpoint - " + e.getMessage(); |
| 92 | + //Check if a 'PsiFile', display without a package name if no PsiFile. |
| 93 | + PsiFile psiFile = PsiDocumentManager.getInstance(module.getProject()).getPsiFile(document); |
| 94 | + if(psiFile == null) { |
| 95 | + return null; |
131 | 96 | } |
132 | 97 |
|
133 | | - |
134 | | - String metadataJson = metadataResponse.toString(); |
135 | | - Gson gson = new Gson(); |
136 | | - try { |
137 | | - ServiceStackMetadata metadata = gson.fromJson(metadataJson, ServiceStackMetadata.class); |
138 | | - if (metadata == null || metadata.getConfig() == null || metadata.getConfig().getBaseUrl() == null) { |
139 | | - errorMessage = "The address url is not a valid ServiceStack endpoint."; |
140 | | - } |
141 | | - } catch (Exception e) { |
142 | | - errorMessage = "The address url is not a valid ServiceStack endpoint."; |
143 | | - } |
144 | | - |
145 | | - if(errorMessage != null) { |
146 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", errorMessage, NotificationType.ERROR); |
147 | | - Notifications.Bus.notify(notification); |
148 | | - return false; |
| 98 | + if(!isJavaFile(psiFile)) { |
| 99 | + return null; |
149 | 100 | } |
150 | | - |
151 | | - return true; |
| 101 | + return (PsiJavaFile)psiFile; |
152 | 102 | } |
153 | 103 |
|
154 | | - @Override |
155 | | - public void invoke(@NotNull Project project, Editor editor, final PsiFile psiFile) throws IncorrectOperationException { |
156 | | - String code = psiFile.getText(); |
157 | | - Scanner scanner = new Scanner(code); |
158 | | - List<String> linesOfCode = new ArrayList<>(); |
159 | | - while (scanner.hasNextLine()) { |
160 | | - String line = scanner.nextLine(); |
161 | | - linesOfCode.add(line); |
162 | | - if(line.startsWith("*/")) break; |
163 | | - } |
164 | | - scanner.close(); |
165 | | - |
166 | | - int startParamsIndex = 0; |
167 | | - String baseUrl = null; |
168 | | - for(String item : linesOfCode) { |
169 | | - startParamsIndex++; |
170 | | - if(item.startsWith("BaseUrl:")) { |
171 | | - baseUrl = item.split(":",2)[1].trim(); |
172 | | - break; |
173 | | - } |
174 | | - } |
175 | | - if(baseUrl == null) { |
176 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", "BaseUrl property not found.", NotificationType.ERROR); |
177 | | - Notifications.Bus.notify(notification); |
178 | | - return; |
179 | | - } |
180 | | - if(!baseUrl.endsWith("/")) { |
181 | | - baseUrl += "/"; |
182 | | - } |
183 | | - |
184 | | - URIBuilder builder = null; |
185 | | - try { |
186 | | - builder = new URIBuilder(baseUrl); |
187 | | - } catch (URISyntaxException e) { |
188 | | - //Log error to IDEA warning bubble/window. |
189 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", "Invalid BaseUrl provided", NotificationType.ERROR); |
190 | | - Notifications.Bus.notify(notification); |
191 | | - return; |
192 | | - } |
| 104 | + private static boolean isJavaFile(@Nullable PsiFile psiFile) { |
| 105 | + return psiFile != null && psiFile instanceof PsiJavaFile; |
| 106 | + } |
193 | 107 |
|
194 | | - String existingPath = builder.getPath(); |
195 | | - if(existingPath == null || existingPath.equals("/")) { |
196 | | - builder.setPath("/types/java"); |
| 108 | + static Module getModule(AnActionEvent e) { |
| 109 | + Module module = e.getData(DataKeys.MODULE); |
| 110 | + if (module == null) { |
| 111 | + Project project = e.getData(DataKeys.PROJECT); |
| 112 | + return getModule(project); |
197 | 113 | } else { |
198 | | - builder.setPath(existingPath + "/types/java"); |
199 | | - } |
200 | | - |
201 | | - |
202 | | - try { |
203 | | - if(!validateEndPoint(builder.build().toString())) { |
204 | | - return; |
205 | | - } |
206 | | - } catch (URISyntaxException e) { |
207 | | - e.printStackTrace(); |
208 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", "Unable to parse BaseUrl", NotificationType.ERROR); |
209 | | - Notifications.Bus.notify(notification); |
210 | | - return; |
211 | | - } |
212 | | - |
213 | | - for(int i = startParamsIndex; i < linesOfCode.size(); i++) { |
214 | | - String configLine = linesOfCode.get(i); |
215 | | - if(!configLine.startsWith("//") && configLine.contains(":")) { |
216 | | - String[] keyVal = configLine.split(":"); |
217 | | - builder.addParameter(keyVal[0],keyVal[1].trim()); |
218 | | - } |
| 114 | + return module; |
219 | 115 | } |
220 | | - |
221 | | - try { |
222 | | - String serverUrl = builder.build().toString(); |
223 | | - URL javaCodeUrl = new URL(serverUrl); |
224 | | - |
225 | | - URLConnection javaCodeConnection = javaCodeUrl.openConnection(); |
226 | | - javaCodeConnection.setRequestProperty("content-type", "application/json; charset=utf-8"); |
227 | | - BufferedReader javaCodeBufferReader = new BufferedReader( |
228 | | - new InputStreamReader( |
229 | | - javaCodeConnection.getInputStream())); |
230 | | - String javaCodeInput; |
231 | | - StringBuilder javaCodeResponse = new StringBuilder(); |
232 | | - while ((javaCodeInput = javaCodeBufferReader.readLine()) != null) { |
233 | | - javaCodeResponse.append(javaCodeInput); |
234 | | - //All documents inside IntelliJ IDEA always use \n line separators. |
235 | | - //http://confluence.jetbrains.net/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview |
236 | | - javaCodeResponse.append("\n"); |
237 | | - } |
238 | | - |
239 | | - Document document = FileDocumentManager.getInstance().getDocument(psiFile.getVirtualFile()); |
240 | | - if (document != null) { |
241 | | - document.setText(javaCodeResponse); |
242 | | - } else { |
243 | | - //Show error |
244 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", "DTO file not found.", NotificationType.ERROR); |
245 | | - Notifications.Bus.notify(notification); |
246 | | - } |
247 | | - } catch (Exception e) { |
248 | | - Notification notification = new Notification("ServiceStackIDEA", "Error Updating Reference", "Invalid BaseUrl provided", NotificationType.ERROR); |
249 | | - Notifications.Bus.notify(notification); |
250 | | - e.printStackTrace(); |
251 | | - } |
252 | | - } |
253 | | - |
254 | | - @Override |
255 | | - public boolean startInWriteAction() { |
256 | | - return true; |
257 | | - } |
258 | | - |
259 | | - @Override |
260 | | - public Icon getIcon(@IconFlags int i) { |
261 | | - return new ImageIcon(this.getClass().getResource("/icons/logo-16.png")); |
262 | 116 | } |
263 | 117 | } |
0 commit comments