|
1 | 1 | package com.sap.adt.abapcleaner.gui.eclipse; |
2 | 2 |
|
3 | 3 | import java.io.InputStream; |
| 4 | +import java.util.HashMap; |
| 5 | +import java.util.concurrent.TimeoutException; |
| 6 | +import java.util.concurrent.atomic.AtomicReference; |
4 | 7 |
|
5 | 8 | import org.eclipse.core.commands.ExecutionEvent; |
6 | 9 | import org.eclipse.core.commands.ExecutionException; |
7 | 10 | import org.eclipse.core.resources.IFile; |
| 11 | +import org.eclipse.core.resources.IProject; |
8 | 12 | import org.eclipse.core.resources.ResourcesPlugin; |
| 13 | +import org.eclipse.core.runtime.IProgressMonitor; |
9 | 14 | import org.eclipse.core.runtime.IStatus; |
| 15 | +import org.eclipse.core.runtime.NullProgressMonitor; |
10 | 16 | import org.eclipse.core.runtime.Status; |
| 17 | +import org.eclipse.core.runtime.jobs.Job; |
11 | 18 | import org.eclipse.jface.dialogs.MessageDialog; |
12 | 19 | import org.eclipse.jface.resource.ColorRegistry; |
13 | 20 | import org.eclipse.jface.resource.JFaceResources; |
@@ -52,7 +59,7 @@ public abstract class AbapCleanerHandlerBase extends AbstractAdtEditorHandler { |
52 | 59 |
|
53 | 60 | private boolean interactive; |
54 | 61 | private boolean readOnly; |
55 | | - |
| 62 | + |
56 | 63 | protected AbapCleanerHandlerBase(boolean interactive, boolean readOnly) { |
57 | 64 | this.interactive = interactive; |
58 | 65 | this.readOnly = readOnly; |
@@ -91,12 +98,12 @@ public Object execute(ExecutionEvent event) throws ExecutionException { |
91 | 98 | CleanupRange cleanupRange = CleanupRange.create(startLine, lastLine, expandRange); |
92 | 99 |
|
93 | 100 | // get the ABAP release against which this code must compile |
94 | | - IPadFileResolver resolver = new PadFileResolver(file.getProject()); |
95 | | - try (InputStream is = resolver.getPadFileContent()) { |
96 | | - // do nothing, just to load data |
| 101 | + IPadFileResolver resolver = adtSourcePage.getPadFileResolver(); |
| 102 | + String abapRelease = resolver.getRelease(); // e.g. "757" if adtSourcePage contains ABAP code |
| 103 | + if (!ABAP.consistsOfDigitsOnly(abapRelease)) { // e.g. "abapddl_32" if adtSourcePage contains DDL |
| 104 | + abapRelease = getAbapReleaseOfProject(file.getProject()); |
97 | 105 | } |
98 | | - String abapRelease = resolver.getRelease(); // e.g. "757" |
99 | | - |
| 106 | + |
100 | 107 | // get the workspace directory |
101 | 108 | String workspaceDir = ResourcesPlugin.getWorkspace().getRoot().getLocation().toString(); |
102 | 109 |
|
@@ -128,6 +135,54 @@ else if (result.hasErrorMessage()) |
128 | 135 | return null; |
129 | 136 | } |
130 | 137 |
|
| 138 | + private static HashMap<String, String> abapReleaseOfProjectName = new HashMap<>(); |
| 139 | + |
| 140 | + private String getAbapReleaseOfProject(IProject project) { |
| 141 | + final int TIMEOUT_MS = 5000; |
| 142 | + |
| 143 | + // use buffered ABAP release, if available for the project name |
| 144 | + String projectName = project.getName(); |
| 145 | + String bufferedAbapRelease = abapReleaseOfProjectName.get(projectName); |
| 146 | + if (bufferedAbapRelease != null) { |
| 147 | + return bufferedAbapRelease; |
| 148 | + } |
| 149 | + |
| 150 | + final AtomicReference<String> abapRelease = new AtomicReference<String>(); |
| 151 | + abapRelease.set(ABAP.FALLBACK_RELEASE); |
| 152 | + |
| 153 | + // since this method is called in the main thread, we must switch to a non-UI thread: otherwise, |
| 154 | + // PadFileResolver.getRelease(String, ABAPRndParser, boolean) will return null and itself start |
| 155 | + // a non-UI thread to retrieve the ABAP release asynchronously, so the UI is not being blocked. |
| 156 | + Job job = new Job("Get ABAP Release of Project " + projectName) { //$NON-NLS-1$ |
| 157 | + @Override |
| 158 | + protected IStatus run(IProgressMonitor monitor) { |
| 159 | + try { |
| 160 | + PadFileResolver resolver = new PadFileResolver(project); |
| 161 | + try (InputStream is = resolver.getPadFileContent()) { |
| 162 | + // do nothing, just to load data |
| 163 | + } |
| 164 | + abapRelease.set(resolver.getRelease()); |
| 165 | + abapReleaseOfProjectName.put(projectName, abapRelease.get()); |
| 166 | + } catch (Exception e) { |
| 167 | + } |
| 168 | + return Status.OK_STATUS; |
| 169 | + } |
| 170 | + }; |
| 171 | + job.setSystem(true); |
| 172 | + job.schedule(); |
| 173 | + |
| 174 | + // for our purpose, make the main thread wait until the job is finished or the timeout is reached |
| 175 | + try { |
| 176 | + if (!job.join(TIMEOUT_MS, new NullProgressMonitor())) { |
| 177 | + throw new TimeoutException(); |
| 178 | + } |
| 179 | + } catch (InterruptedException | TimeoutException e) { |
| 180 | + // use the "fallback" release, thus blocking all cleanup rules that require a certain (minimum) release |
| 181 | + abapRelease.set(ABAP.FALLBACK_RELEASE); |
| 182 | + } |
| 183 | + return abapRelease.get(); |
| 184 | + } |
| 185 | + |
131 | 186 | private CodeDisplayColors createCodeDisplayColors(ColorProfile colorProfile) { |
132 | 187 | final String namePrefix = "com.sap.adt.tools.abapsource.ui."; |
133 | 188 |
|
|
0 commit comments