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.SortedSet;
13  import java.util.prefs.Preferences;
14  
15  import javax.swing.SwingUtilities;
16  import javax.swing.text.BadLocationException;
17  import javax.swing.text.StyledDocument;
18  
19  import org.apache.commons.lang3.StringUtils;
20  import org.apache.commons.lang3.tuple.Pair;
21  import org.openide.awt.NotificationDisplayer;
22  import org.openide.awt.StatusDisplayer;
23  
24  import com.github.vertical_blank.sqlformatter.core.FormatConfig;
25  import com.github.vertical_blank.sqlformatter.languages.Dialect;
26  
27  import de.funfried.netbeans.plugins.external.formatter.AbstractFormatJob;
28  import de.funfried.netbeans.plugins.external.formatter.exceptions.FormattingFailedException;
29  import de.funfried.netbeans.plugins.external.formatter.ui.Icons;
30  import de.funfried.netbeans.plugins.external.formatter.ui.options.Settings;
31  
32  /**
33   * Vertical Blank SQL formatter implementation of the {@link AbstractFormatJob} to
34   * format a given document using the {@link SQLFormatterWrapper}.
35   *
36   * @author bahlef
37   */
38  class SQLFormatterJob extends AbstractFormatJob {
39  	/** The Vertical Blank SQL Formatter implementation. */
40  	private final SQLFormatterWrapper formatter;
41  
42  	/**
43  	 * Package private constructor to create a new instance of {@link SQLFormatterJob}.
44  	 *
45  	 * @param document the {@link StyledDocument} which sould be formatted
46  	 * @param formatter the {@link SQLFormatterWrapper} to use
47  	 * @param changedElements the ranges which should be formatted
48  	 */
49  	SQLFormatterJob(StyledDocument document, SQLFormatterWrapper formatter, SortedSet<Pair<Integer, Integer>> changedElements) {
50  		super(document, changedElements);
51  
52  		this.formatter = formatter;
53  	}
54  
55  	/**
56  	 * {@inheritDoc}
57  	 */
58  	@Override
59  	public void format() throws BadLocationException {
60  		Preferences pref = Settings.getActivePreferences(document);
61  
62  		String code = getCode();
63  
64  		try {
65  			String formattedContent = formatter.format(code, getDialect(pref), getFormatConfig(pref));
66  
67  			if (setFormattedCode(code, formattedContent)) {
68  				SwingUtilities.invokeLater(() -> {
69  					if (pref.getBoolean(Settings.SHOW_NOTIFICATIONS, false)) {
70  						NotificationDisplayer.getDefault().notify("Format using Vertical Blank SQL formatter", Icons.ICON_EXTERNAL, "", null);
71  					}
72  					StatusDisplayer.getDefault().setStatusText("Format using Vertical Blank SQL formatter");
73  				});
74  			}
75  		} catch (FormattingFailedException ex) {
76  			SwingUtilities.invokeLater(() -> {
77  				StatusDisplayer.getDefault().setStatusText("Failed to format using Vertical Blank SQL formatter: " + ex.getMessage());
78  			});
79  
80  			throw ex;
81  		}
82  	}
83  
84  	private Dialect getDialect(Preferences pref) {
85  		return Dialect.valueOf(pref.get(SQLFormatterSettings.DIALECT, SQLFormatterSettings.DIALECT_DEFAULT));
86  	}
87  
88  	private FormatConfig getFormatConfig(Preferences pref) {
89  		int indentSize = pref.getInt(SQLFormatterSettings.INDENT_SIZE, SQLFormatterSettings.INDENT_SIZE_DEFAULT);
90  		char indentSign = pref.getBoolean(SQLFormatterSettings.EXPAND_TABS_TO_SPACES, SQLFormatterSettings.EXPAND_TABS_TO_SPACES_DEFAULT) ? ' ' : '\t';
91  
92  		String indent = StringUtils.repeat(indentSign, indentSize);
93  
94  		return FormatConfig.builder()
95  				.indent(indent)
96  				.linesBetweenQueries(pref.getInt(SQLFormatterSettings.LINES_BETWEEN_QUERIES, SQLFormatterSettings.LINES_BETWEEN_QUERIES_DEFAULT))
97  				.maxColumnLength(pref.getInt(SQLFormatterSettings.MAX_COLUMN_LENGTH, SQLFormatterSettings.MAX_COLUMN_LENGTH_DEFAULT))
98  				.uppercase(pref.getBoolean(SQLFormatterSettings.UPPERCASE, SQLFormatterSettings.UPPERCASE_DEFAULT))
99  				.build();
100 	}
101 }