View Javadoc
1   /*
2    * Copyright (c) 2021 Andreas Reichel <a href="mailto:andreas@manticore-projects.com">andreas@manticore-projects.com</a>
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v2.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v20.html
7    * Contributors:
8    * bahlef - initial API and implementation and/or initial documentation
9    */
10  package de.funfried.netbeans.plugins.external.formatter.sql.sqlformatter;
11  
12  import java.util.Collections;
13  import java.util.List;
14  import java.util.SortedSet;
15  import java.util.prefs.Preferences;
16  
17  import javax.swing.text.BadLocationException;
18  import javax.swing.text.Document;
19  import javax.swing.text.StyledDocument;
20  
21  import org.apache.commons.lang3.tuple.Pair;
22  import org.netbeans.api.annotations.common.CheckForNull;
23  import org.netbeans.api.annotations.common.NonNull;
24  import org.netbeans.api.project.Project;
25  import org.openide.util.NbBundle;
26  import org.openide.util.lookup.ServiceProvider;
27  
28  import de.funfried.netbeans.plugins.external.formatter.FormatJob;
29  import de.funfried.netbeans.plugins.external.formatter.FormatterService;
30  import de.funfried.netbeans.plugins.external.formatter.MimeType;
31  import de.funfried.netbeans.plugins.external.formatter.exceptions.FormattingFailedException;
32  import de.funfried.netbeans.plugins.external.formatter.sql.sqlformatter.ui.SQLFormatterOptionsPanel;
33  import de.funfried.netbeans.plugins.external.formatter.ui.options.FormatterOptionsPanel;
34  import de.funfried.netbeans.plugins.external.formatter.ui.options.Settings;
35  
36  /**
37   * Vertical Blank SQL formatter implementation of the {@link FormatterService}.
38   *
39   * @author bahlef
40   */
41  @NbBundle.Messages({
42  		"FormatterName=Vertical Blank SQL Formatter"
43  })
44  @ServiceProvider(service = FormatterService.class, position = 500)
45  public class SQLFormatterService implements FormatterService {
46  	/** The ID of this formatter service. */
47  	public static final String ID = "vertical-blank-sql-formatter";
48  
49  	/** * The {@link SQLFormatterWrapper} implementation. */
50  	private final SQLFormatterWrapper formatter = new SQLFormatterWrapper();
51  
52  	/**
53  	 * {@inheritDoc}
54  	 */
55  	@Override
56  	public boolean format(StyledDocument document, SortedSet<Pair<Integer, Integer>> changedElements) throws BadLocationException, FormattingFailedException {
57  		if (!canHandle(document)) {
58  			throw new FormattingFailedException("The file type '" + MimeType.getMimeTypeAsString(document) + "' is not supported");
59  		}
60  
61  		getFormatJob(document, changedElements).format();
62  
63  		return true;
64  	}
65  
66  	/**
67  	 * {@inheritDoc}
68  	 */
69  	@Override
70  	public List<MimeType> getSupportedMimeTypes() {
71  		return Collections.singletonList(MimeType.SQL);
72  	}
73  
74  	/**
75  	 * {@inheritDoc}
76  	 */
77  	@NonNull
78  	@Override
79  	public String getDisplayName() {
80  		return NbBundle.getMessage(SQLFormatterService.class, "FormatterName");
81  	}
82  
83  	/**
84  	 * {@inheritDoc}
85  	 */
86  	@NonNull
87  	@Override
88  	public String getId() {
89  		return ID;
90  	}
91  
92  	/**
93  	 * {@inheritDoc}
94  	 */
95  	@Override
96  	public FormatterOptionsPanel createOptionsPanel(Project project) {
97  		return new SQLFormatterOptionsPanel(project);
98  	}
99  
100 	/**
101 	 * {@inheritDoc}
102 	 */
103 	@CheckForNull
104 	@Override
105 	public Integer getContinuationIndentSize(Document document) {
106 		if (document == null) {
107 			return null;
108 		}
109 
110 		Integer width = null;
111 
112 		Preferences preferences = Settings.getActivePreferences(document);
113 		if (isUseFormatterIndentationSettings(preferences)) {
114 			width = preferences.getInt(SQLFormatterSettings.INDENT_SIZE, SQLFormatterSettings.INDENT_SIZE_DEFAULT);
115 		}
116 
117 		return width;
118 	}
119 
120 	/**
121 	 * {@inheritDoc}
122 	 */
123 	@CheckForNull
124 	@Override
125 	public Integer getIndentSize(Document document) {
126 		if (document == null) {
127 			return null;
128 		}
129 
130 		Integer width = null;
131 
132 		Preferences preferences = Settings.getActivePreferences(document);
133 		if (isUseFormatterIndentationSettings(preferences)) {
134 			width = preferences.getInt(SQLFormatterSettings.INDENT_SIZE, SQLFormatterSettings.INDENT_SIZE_DEFAULT);
135 		}
136 
137 		return width;
138 	}
139 
140 	/**
141 	 * {@inheritDoc}
142 	 */
143 	@CheckForNull
144 	@Override
145 	public Integer getRightMargin(Document document) {
146 		if (document == null) {
147 			return null;
148 		}
149 
150 		Preferences preferences = Settings.getActivePreferences(document);
151 		return preferences.getInt(SQLFormatterSettings.MAX_COLUMN_LENGTH, SQLFormatterSettings.MAX_COLUMN_LENGTH_DEFAULT);
152 	}
153 
154 	/**
155 	 * Returns the {@link FormatJob}.
156 	 *
157 	 * @param document the {@link StyledDocument} which should be formatted
158 	 * @param changedElements a {@link SortedSet} containing ranges as {@link Pair} objects that should be formatted
159 	 */
160 	protected FormatJob getFormatJob(StyledDocument document, SortedSet<Pair<Integer, Integer>> changedElements) {
161 		return new SQLFormatterJob(document, formatter, changedElements);
162 	}
163 
164 	/**
165 	 * {@inheritDoc}
166 	 */
167 	@CheckForNull
168 	@Override
169 	public Integer getSpacesPerTab(Document document) {
170 		if (document == null) {
171 			return null;
172 		}
173 
174 		Integer ret = null;
175 
176 		Preferences preferences = Settings.getActivePreferences(document);
177 		if (isUseFormatterIndentationSettings(preferences)) {
178 			if (!isExpandTabToSpaces(document, preferences) && preferences.getBoolean(Settings.OVERRIDE_TAB_SIZE, true)) {
179 				ret = preferences.getInt(Settings.OVERRIDE_TAB_SIZE_VALUE, 4);
180 			} else {
181 				ret = preferences.getInt(SQLFormatterSettings.INDENT_SIZE, SQLFormatterSettings.INDENT_SIZE_DEFAULT);
182 			}
183 		}
184 
185 		return ret;
186 	}
187 
188 	/**
189 	 * {@inheritDoc}
190 	 */
191 	@CheckForNull
192 	@Override
193 	public Boolean isExpandTabToSpaces(Document document) {
194 		if (document == null) {
195 			return null;
196 		}
197 
198 		return isExpandTabToSpaces(document, Settings.getActivePreferences(document));
199 	}
200 
201 	private Boolean isExpandTabToSpaces(Document document, Preferences preferences) {
202 		if (document == null || preferences == null) {
203 			return null;
204 		}
205 
206 		if (isUseFormatterIndentationSettings(preferences)) {
207 			return preferences.getBoolean(SQLFormatterSettings.EXPAND_TABS_TO_SPACES, SQLFormatterSettings.EXPAND_TABS_TO_SPACES_DEFAULT);
208 		}
209 
210 		return null;
211 	}
212 
213 	/**
214 	 * Returns {@code true} if using the formatter indentation settings from the external
215 	 * formatter is activated, otherwise {@code false}.
216 	 *
217 	 * @param prefs the {@link Preferences} where to check
218 	 *
219 	 * @return {@code true} if using the formatter indentation settings from the external
220 	 *         formatter is activated, otherwise {@code false}
221 	 */
222 	private boolean isUseFormatterIndentationSettings(Preferences prefs) {
223 		return prefs.getBoolean(Settings.ENABLE_USE_OF_INDENTATION_SETTINGS, true);
224 	}
225 
226 	/**
227 	 * {@inheritDoc}
228 	 */
229 	@Override
230 	@CheckForNull
231 	public Boolean organizeImports(StyledDocument document, boolean afterFixImports) throws BadLocationException {
232 		return null;
233 	}
234 }