View Javadoc
1   /*
2    * Copyright (c) 2020 bahlef.
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.java.eclipse;
11  
12  import java.util.HashMap;
13  import java.util.LinkedHashMap;
14  import java.util.Map;
15  
16  import org.apache.commons.lang3.StringUtils;
17  import org.eclipse.jdt.core.JavaCore;
18  import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
19  
20  import de.funfried.netbeans.plugins.external.formatter.eclipse.xml.EclipseFormatterUtils;
21  import de.funfried.netbeans.plugins.external.formatter.exceptions.CannotLoadConfigurationException;
22  import de.funfried.netbeans.plugins.external.formatter.exceptions.ConfigReadException;
23  import de.funfried.netbeans.plugins.external.formatter.exceptions.ProfileNotFoundException;
24  
25  /**
26   * Class used for parsing an Eclipse code formatter configuration.
27   *
28   * @author bahlef
29   */
30  @SuppressWarnings("unchecked")
31  public final class EclipseFormatterConfig {
32  	/** Prefix for workspace mechanic files. */
33  	private static final String WORKSPACE_MECHANIC_PREFIX = "/instance/org.eclipse.jdt.core/";
34  
35  	/** Default configuration of the Eclipse Java formatter. */
36  	private static final Map<String, String> ECLIPSE_JAVA_FORMATTER_DEFAULTS = new LinkedHashMap<>();
37  
38  	static {
39  		ECLIPSE_JAVA_FORMATTER_DEFAULTS.putAll(DefaultCodeFormatterConstants.getJavaConventionsSettings());
40  
41  		String level = JavaCore.VERSION_1_6;
42  		ECLIPSE_JAVA_FORMATTER_DEFAULTS.put(JavaCore.COMPILER_COMPLIANCE, level);
43  		ECLIPSE_JAVA_FORMATTER_DEFAULTS.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, level);
44  		ECLIPSE_JAVA_FORMATTER_DEFAULTS.put(JavaCore.COMPILER_SOURCE, level);
45  	}
46  
47  	/**
48  	 * Private constructor due to static methods only.
49  	 */
50  	private EclipseFormatterConfig() {
51  	}
52  
53  	/**
54  	 * Returns the source level options as a {@link Map}.
55  	 *
56  	 * @param sourceLevel the source level for which to get the options
57  	 *
58  	 * @return {@link IRegion}
59  	 */
60  	private static Map<String, String> getSourceLevelOptions(String sourceLevel) {
61  		Map<String, String> options = new HashMap<>();
62  		if (StringUtils.isNotBlank(sourceLevel)) {
63  			options.put(JavaCore.COMPILER_COMPLIANCE, sourceLevel);
64  			options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, sourceLevel);
65  			options.put(JavaCore.COMPILER_SOURCE, sourceLevel);
66  		}
67  
68  		return options;
69  	}
70  
71  	/**
72  	 * Parses the configuration parameters from the given {@code profile} of the
73  	 * given formatter configuration file and returns it as a {@link Map}
74  	 * containing the configuration as key value pairs.
75  	 *
76  	 * @param formatterFile the path to the formatter configuration file
77  	 * @param formatterProfile the name of the formatter configuration profile
78  	 * @param sourceLevel the source level to use for formatting
79  	 *
80  	 * @return a {@link Map} containing the configuration as key value pairs
81  	 *
82  	 * @throws ConfigReadException if there is an issue parsing the formatter configuration
83  	 * @throws ProfileNotFoundException if the given {@code profile} could not be found
84  	 * @throws CannotLoadConfigurationException if there is any issue accessing or reading the formatter configuration
85  	 */
86  	public static Map<String, String> parseConfig(String formatterFile, String formatterProfile, String sourceLevel)
87  			throws ProfileNotFoundException, ConfigReadException, CannotLoadConfigurationException {
88  		Map<String, String> config = EclipseFormatterUtils.parseConfig(formatterFile, formatterProfile, ECLIPSE_JAVA_FORMATTER_DEFAULTS, getSourceLevelOptions(sourceLevel), WORKSPACE_MECHANIC_PREFIX,
89  				EclipseJavaFormatterSettings.PROJECT_PREF_FILE);
90  
91  		// https://github.com/markiewb/eclipsecodeformatter_for_netbeans/issues/77
92  		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=449262
93  		if (org.eclipse.jdt.core.JavaCore.DEFAULT_JAVA_FORMATTER.equals(config.get("org.eclipse.jdt.core.javaFormatter"))) {
94  			//ignore default formatter as configured extension point
95  			config.remove("org.eclipse.jdt.core.javaFormatter");
96  		}
97  
98  		if (null != config.get("org.eclipse.jdt.core.javaFormatter")) {
99  			throw new CannotLoadConfigurationException("The use of third-party Java code formatters is not supported by this plugin.\n"
100 					+ "See https://github.com/markiewb/eclipsecodeformatter_for_netbeans/issues/77\n"
101 					+ "Try to remove the entry 'org.eclipse.jdt.core.javaFormatter' from the configuration.");
102 		}
103 
104 		return config;
105 	}
106 }