1
2
3
4
5
6
7
8
9
10 package de.funfried.netbeans.plugins.external.formatter.java.spring;
11
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.util.Objects;
15 import java.util.Properties;
16 import java.util.SortedSet;
17 import java.util.logging.Level;
18 import java.util.logging.Logger;
19 import java.util.prefs.Preferences;
20
21 import javax.swing.text.BadLocationException;
22 import javax.swing.text.Document;
23 import javax.swing.text.StyledDocument;
24
25 import org.apache.commons.lang3.tuple.Pair;
26 import org.netbeans.api.annotations.common.CheckForNull;
27 import org.netbeans.api.annotations.common.NonNull;
28 import org.netbeans.api.project.Project;
29 import org.openide.util.NbBundle;
30 import org.openide.util.lookup.ServiceProvider;
31
32 import de.funfried.netbeans.plugins.external.formatter.FormatterService;
33 import de.funfried.netbeans.plugins.external.formatter.java.base.AbstractJavaFormatterService;
34 import de.funfried.netbeans.plugins.external.formatter.java.spring.ui.SpringJavaFormatterOptionsPanel;
35 import de.funfried.netbeans.plugins.external.formatter.ui.options.FormatterOptionsPanel;
36 import de.funfried.netbeans.plugins.external.formatter.ui.options.Settings;
37 import io.spring.javaformat.formatter.eclipse.EclipseCodeFormatter;
38
39
40
41
42
43
44 @NbBundle.Messages({
45 "FormatterName=Spring Java Code Formatter"
46 })
47 @ServiceProvider(service = FormatterService.class, position = 1500)
48 public class SpringJavaFormatterService extends AbstractJavaFormatterService<SpringFormatJob> {
49
50 private static final Logger log = Logger.getLogger(SpringJavaFormatterService.class.getName());
51
52
53 public static final String ID = "spring-java-formatter";
54
55
56 private final SpringJavaFormatterWrapper formatter = new SpringJavaFormatterWrapper();
57
58
59
60
61 @NonNull
62 @Override
63 public String getDisplayName() {
64 return NbBundle.getMessage(SpringJavaFormatterService.class, "FormatterName");
65 }
66
67
68
69
70 @NonNull
71 @Override
72 public String getId() {
73 return ID;
74 }
75
76
77
78
79 @Override
80 public FormatterOptionsPanel createOptionsPanel(Project project) {
81 return new SpringJavaFormatterOptionsPanel(project);
82 }
83
84
85
86
87 @CheckForNull
88 @Override
89 public Integer getContinuationIndentSize(Document document) {
90 if (document == null) {
91 return null;
92 }
93
94 Integer ret = null;
95
96 Preferences preferences = Settings.getActivePreferences(document);
97 if (isUseFormatterIndentationSettings(preferences)) {
98 String propKey = "core.formatter.continuation_indentation";
99 String prop = this.getSpringFormatterProperty(propKey);
100 if (prop != null) {
101 try {
102 ret = Integer.parseInt(prop);
103
104 Integer indentSize = getIndentSize(document);
105 if (indentSize != null) {
106 ret *= indentSize;
107 }
108 } catch (NumberFormatException ex) {
109 log.log(Level.WARNING, "Property '" + propKey + "' is not an integer: " + prop, ex);
110 }
111 }
112
113 if (ret == null) {
114 ret = 2;
115 }
116 }
117
118 return ret;
119 }
120
121
122
123
124 @CheckForNull
125 @Override
126 public Integer getIndentSize(Document document) {
127 if (document == null) {
128 return null;
129 }
130
131 Integer ret = null;
132
133 Preferences preferences = Settings.getActivePreferences(document);
134 if (isUseFormatterIndentationSettings(preferences)) {
135 String tabChar = getSpringFormatterProperty("core.formatter.tabulation.char");
136 if (Objects.equals(tabChar, "mixed")) {
137 String propKey = "core.formatter.indentation.size";
138 String prop = this.getSpringFormatterProperty(propKey);
139 if (prop != null) {
140 try {
141 ret = Integer.parseInt(prop);
142 } catch (NumberFormatException ex) {
143 log.log(Level.WARNING, "Property '" + propKey + "' is not an integer: " + prop, ex);
144 }
145 }
146 } else {
147 ret = getSpacesPerTab(document);
148 }
149
150 if (ret == null) {
151 ret = 4;
152 }
153 }
154
155 return ret;
156 }
157
158
159
160
161 @CheckForNull
162 @Override
163 public Integer getRightMargin(Document document) {
164 if (document == null) {
165 return null;
166 }
167
168 Integer ret = 120;
169
170 String propKey = "core.formatter.lineSplit";
171 String prop = this.getSpringFormatterProperty(propKey);
172 if (prop != null) {
173 try {
174 ret = Integer.parseInt(prop);
175 } catch (NumberFormatException ex) {
176 log.log(Level.WARNING, "Property '" + propKey + "' is not an integer: " + prop, ex);
177 }
178 }
179
180 return ret;
181 }
182
183
184
185
186 @Override
187 protected SpringFormatJob getFormatJob(StyledDocument document, SortedSet<Pair<Integer, Integer>> changedElements) {
188 return new SpringFormatJob(document, formatter, changedElements);
189 }
190
191
192
193
194 @CheckForNull
195 @Override
196 public Integer getSpacesPerTab(Document document) {
197 if (document == null) {
198 return null;
199 }
200
201 Integer ret = null;
202
203 Preferences preferences = Settings.getActivePreferences(document);
204 if (isUseFormatterIndentationSettings(preferences)) {
205 if (!isExpandTabToSpaces(document, preferences) && preferences.getBoolean(Settings.OVERRIDE_TAB_SIZE, true)) {
206 ret = preferences.getInt(Settings.OVERRIDE_TAB_SIZE_VALUE, 4);
207 } else {
208 String propKey = "core.formatter.tabulation.size";
209 String prop = this.getSpringFormatterProperty(propKey);
210 if (prop != null) {
211 try {
212 ret = Integer.parseInt(prop);
213 } catch (NumberFormatException ex) {
214 log.log(Level.WARNING, "Property '" + propKey + "' is not an integer: " + prop, ex);
215 }
216 }
217
218 if (ret == null) {
219 ret = 4;
220 }
221 }
222 }
223
224 return ret;
225 }
226
227
228
229
230
231
232
233
234
235
236 private String getSpringFormatterProperty(String key) {
237 Properties props = new Properties();
238 try (InputStream is = EclipseCodeFormatter.class.getResourceAsStream("formatter.prefs")) {
239 props.load(is);
240 } catch (IOException ex) {
241 log.log(Level.SEVERE, "Could not read internal Spring formatter configuration", ex);
242 }
243
244 return props.getProperty(key);
245 }
246
247
248
249
250 @CheckForNull
251 @Override
252 public Boolean isExpandTabToSpaces(Document document) {
253 if (document == null) {
254 return null;
255 }
256
257 return isExpandTabToSpaces(document, Settings.getActivePreferences(document));
258 }
259
260 @CheckForNull
261 private Boolean isExpandTabToSpaces(Document document, Preferences preferences) {
262 if (document == null || preferences == null) {
263 return null;
264 }
265
266 Boolean ret = null;
267
268 if (isUseFormatterIndentationSettings(preferences)) {
269 String propKey = "core.formatter.tabulation.char";
270 String prop = this.getSpringFormatterProperty(propKey);
271 if (prop != null) {
272 ret = Objects.equals(prop, "space");
273 }
274
275 if (ret == null) {
276 ret = false;
277 }
278 }
279
280 return ret;
281 }
282
283
284
285
286
287
288
289
290
291
292 private boolean isUseFormatterIndentationSettings(Preferences prefs) {
293 return prefs.getBoolean(Settings.ENABLE_USE_OF_INDENTATION_SETTINGS, true);
294 }
295
296
297
298
299 @Override
300 @CheckForNull
301 public Boolean organizeImports(StyledDocument document, boolean afterFixImports) throws BadLocationException {
302 return null;
303 }
304 }