1515 */
1616package com .diffplug .spotless .extra .eclipse .java ;
1717
18- import java .util .Collections ;
1918import java .util .HashMap ;
20- import java .util .Hashtable ;
2119import java .util .List ;
2220import java .util .Map ;
2321import java .util .Properties ;
2725import org .eclipse .core .resources .IFolder ;
2826import org .eclipse .core .resources .IProject ;
2927import org .eclipse .core .resources .IProjectDescription ;
28+ import org .eclipse .core .resources .ProjectScope ;
3029import org .eclipse .core .resources .ResourcesPlugin ;
3130import org .eclipse .core .runtime .IProgressMonitor ;
31+ import org .eclipse .core .runtime .preferences .IEclipsePreferences ;
3232import org .eclipse .jdt .core .IBuffer ;
3333import org .eclipse .jdt .core .ICompilationUnit ;
3434import org .eclipse .jdt .core .IJavaProject ;
3535import org .eclipse .jdt .core .IPackageFragment ;
3636import org .eclipse .jdt .core .IPackageFragmentRoot ;
37- import org .eclipse .jdt .core .IType ;
3837import org .eclipse .jdt .core .JavaCore ;
3938import org .eclipse .jdt .core .JavaModelException ;
39+ import org .eclipse .jdt .core .manipulation .JavaManipulation ;
4040import org .eclipse .jdt .internal .core .BufferManager ;
4141import org .eclipse .jdt .internal .core .CompilationUnit ;
4242import org .eclipse .jdt .internal .core .DefaultWorkingCopyOwner ;
43- import org .eclipse .jdt .internal .core .JavaModelManager ;
43+ import org .eclipse .jdt .internal .core .JavaCorePreferenceInitializer ;
4444import org .eclipse .jdt .internal .core .PackageFragment ;
45+ import org .eclipse .jdt .internal .core .nd .indexer .Indexer ;
4546
4647/**
4748 * Helper methods to create Java compilation unit.
5152 * (see {@code org.eclipse.core.internal.resources.LocationValidator} for details).
5253 * </p>
5354 */
54- class EclipseJdtFactory extends OS {
55+ class EclipseJdtHelper extends OS {
5556
5657 private final static String ROOT_AS_SRC = "" ;
5758 private final static String PROJECT_NAME = "spotless" ;
5859 private final static String SOURCE_NAME = "source.java" ;
59- private final static AtomicInteger UNIQUE_PROJECT_ID = new AtomicInteger ( 0 );
60+ private static EclipseJdtHelper INSTANCE ;
6061
61- private final static Map <String , String > DEFAULT_OPTIONS ;
62-
63- static {
64- Map <String , String > defaultOptions = new HashMap <>();
65- defaultOptions .put (JavaCore .COMPILER_SOURCE , getJavaCoreVersion ());
66- DEFAULT_OPTIONS = Collections .unmodifiableMap (defaultOptions );
62+ static synchronized EclipseJdtHelper getInstance () {
63+ if (null == INSTANCE ) {
64+ INSTANCE = new EclipseJdtHelper ();
65+ }
66+ return INSTANCE ;
6767 }
68+
69+ private final AtomicInteger uniqueProjectId = new AtomicInteger (0 );
70+ private final Map <String , String > defaultOptions ;
71+
72+ private EclipseJdtHelper () {
73+ defaultOptions = new HashMap <>();
74+ defaultOptions .put (JavaCore .COMPILER_SOURCE , getJavaCoreVersion ());
75+
76+ /*
77+ * Assure that the 'allowed keys' are initialized, otherwise
78+ * JProject will not accept any options.
79+ */
80+ new JavaCorePreferenceInitializer ().initializeDefaultPreferences ();
81+
82+ /*
83+ * Don't run indexer in background (does not disable thread but the job scheduling)
84+ */
85+ Indexer .getInstance ().enableAutomaticIndexing (false );
86+ }
6887
6988 private static String getJavaCoreVersion () {
7089 final String javaVersion = System .getProperty ("java.version" );
@@ -76,30 +95,41 @@ private static String getJavaCoreVersion() {
7695 }
7796 return orderedSupportedCoreVersions .get (orderedSupportedCoreVersions .size () - 1 );
7897 }
79-
98+
8099 /**
81100 * Creates a JAVA project and applies the configuration.
82101 * @param settings Configuration settings
83102 * @return Configured JAVA project
84103 * @throws Exception In case the project creation fails
85104 */
86- public final static IJavaProject createProject (Properties settings ) throws Exception {
87- String uniqueProjectName = String .format ("%s-%d" , PROJECT_NAME , UNIQUE_PROJECT_ID .incrementAndGet ());
105+ IJavaProject createProject (Properties settings ) throws Exception {
106+ String uniqueProjectName = String .format ("%s-%d" , PROJECT_NAME , uniqueProjectId .incrementAndGet ());
88107 IProject project = ResourcesPlugin .getWorkspace ().getRoot ().getProject (uniqueProjectName );
89108 // The project must be open before items (natures, folders, sources, ...) can be created
90109 project .create (null );
91110 project .open (0 , null );
92- //If the project nature is not set, things like AST are not created for the Java projects
111+
112+ //If the project nature is not set, the AST is not created for the compilation units
93113 IProjectDescription description = project .getDescription ();
94114 description .setNatureIds (new String []{JavaCore .NATURE_ID });
95115 project .setDescription (description , null );
96116 IJavaProject jProject = JavaCore .create (project );
97117
98- Map <String , String > settingsMap = new HashMap <>(DEFAULT_OPTIONS );
118+ Map <String , String > allSettings = new HashMap <>(defaultOptions );
99119 settings .forEach ((key , value ) -> {
100- settingsMap .put (key .toString (), value .toString ());
120+ allSettings .put (key .toString (), value .toString ());
101121 });
102- jProject .setOptions (settingsMap );
122+ //Configure JDT manipulation processor
123+ IEclipsePreferences projectPrefs = new ProjectScope (project .getProject ()).getNode (JavaManipulation .getPreferenceNodeId ());
124+ allSettings .forEach ((key , value ) -> {
125+ projectPrefs .put (key .toString (), value .toString ());
126+ });
127+ /*
128+ * Configure options taken directly from the Java project (without qualifier).
129+ * Whether a setting is a Java project option or not, is filtered by the
130+ * JavaCorePreferenceInitializer, initialized by the constructor of this class.
131+ */
132+ jProject .setOptions (allSettings );
103133
104134 // Eclipse source files require an existing source folder for creation
105135 IPackageFragmentRoot src = jProject .getPackageFragmentRoot (jProject .getProject ());
@@ -110,27 +140,22 @@ public final static IJavaProject createProject(Properties settings) throws Excep
110140 // Eclipse clean-up requires an existing source file
111141 pkg .createCompilationUnit (SOURCE_NAME , "" , true , null );
112142
113- //
114- disableSecondaryTypes (project );
115-
116143 return jProject ;
117144 }
118145
119- private static void disableSecondaryTypes (IProject project ) {
120- JavaModelManager .PerProjectInfo info = JavaModelManager .getJavaModelManager ().getPerProjectInfo (project , true );
121- info .secondaryTypes = new Hashtable <String , Map <String , IType >>();
122- }
123-
124- public static ICompilationUnit createJavaSource (String contents , IJavaProject jProject ) throws Exception {
146+ ICompilationUnit createCompilationUnit (String contents , IJavaProject jProject ) throws Exception {
125147 IPackageFragmentRoot src = jProject .getPackageFragmentRoot (jProject .getProject ());
126148 IPackageFragment pkg = src .getPackageFragment (ROOT_AS_SRC );
127149 return new RamCompilationUnit ((PackageFragment ) pkg , contents );
128150 }
129151
130- /** Spotless keeps compilation units in RAM as long as they are worked on. */
152+ /** Keep compilation units in RAM */
131153 private static class RamCompilationUnit extends CompilationUnit {
132154
133- //Each RMA compilation unit has its own buffer manager. A drop is therefore prevented.
155+ /*
156+ * Each RAM compilation unit has its own buffer manager to
157+ * prevent dropping of CUs when a maximum size is reached.
158+ */
134159 private final RamBufferManager manager ;
135160
136161 RamCompilationUnit (PackageFragment parent , String contents ) {
@@ -153,7 +178,7 @@ protected BufferManager getBufferManager() {
153178
154179 @ Override
155180 public void save (IProgressMonitor pm , boolean force ) throws JavaModelException {
156- //RAM CU is never saved to disk
181+ //RAM CU is never stored on disk
157182 }
158183
159184 @ Override
@@ -167,7 +192,7 @@ public boolean equals(Object obj) {
167192 }
168193 }
169194
170- /** Work- around required package privileges when adding buffer for manager singleton */
195+ /** Work around package privileges */
171196 private static class RamBufferManager extends BufferManager {
172197 void add (IBuffer buffer ) {
173198 addBuffer (buffer );
0 commit comments