Skip to content

Commit 1fc8e32

Browse files
eharris369GitHub Enterprise
authored andcommitted
Merge pull request #187 from eharris/185-supportValidationAndQuickFixes
Issue #185: Add support for validation and quick fixes
2 parents 7027f28 + 18f0c60 commit 1fc8e32

19 files changed

+474
-5
lines changed

dev/com.ibm.microclimate.core/plugin.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ MICROCLIMATE_SERVER_ID=microclimate.server
1717
SERVER_NAME=Microclimate Server
1818
SERVER_DESCRIPTION=Server representing a Microclimate project
1919

20-
LAUNCH_CONFIG_NAME=Microclimate Project
20+
LAUNCH_CONFIG_NAME=Microclimate Project
21+
22+
VALIDATION_MARKER=Microclimate Problem

dev/com.ibm.microclimate.core/plugin.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,11 @@
3131
</sourcePathComputer>
3232
</extension>
3333

34+
<extension point="org.eclipse.core.resources.markers"
35+
id="validationMarker"
36+
name="%VALIDATION_MARKER">
37+
<persistent value="true"/>
38+
<super type="org.eclipse.core.resources.problemmarker"/>
39+
</extension>
3440

3541
</plugin>

dev/com.ibm.microclimate.core/src/com/ibm/microclimate/core/internal/MCEclipseApplication.java

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,16 @@
1414
import java.util.List;
1515

1616
import org.eclipse.core.resources.IContainer;
17+
import org.eclipse.core.resources.IFile;
18+
import org.eclipse.core.resources.IMarker;
19+
import org.eclipse.core.resources.IProject;
20+
import org.eclipse.core.resources.IResource;
21+
import org.eclipse.core.resources.ResourcesPlugin;
22+
import org.eclipse.core.runtime.CoreException;
23+
import org.eclipse.core.runtime.IPath;
1724
import org.eclipse.core.runtime.IProgressMonitor;
1825
import org.eclipse.core.runtime.IStatus;
26+
import org.eclipse.core.runtime.Path;
1927
import org.eclipse.core.runtime.Status;
2028
import org.eclipse.core.runtime.jobs.Job;
2129
import org.eclipse.debug.core.DebugPlugin;
@@ -38,6 +46,13 @@
3846

3947
public class MCEclipseApplication extends MicroclimateApplication {
4048

49+
// Validation marker
50+
public static final String MARKER_TYPE = MicroclimateCorePlugin.PLUGIN_ID + ".validationMarker";
51+
public static final String CONNECTION_URL = "connectionUrl";
52+
public static final String PROJECT_ID = "projectId";
53+
public static final String QUICK_FIX_ID = "quickFixId";
54+
public static final String QUICK_FIX_DESCRIPTION = "quickFixDescription";
55+
4156
// in seconds
4257
public static final int DEFAULT_DEBUG_CONNECT_TIMEOUT = 3;
4358

@@ -89,7 +104,7 @@ public synchronized ILaunch getLaunch() {
89104
@Override
90105
public void connectDebugger() {
91106
final MCEclipseApplication app = this;
92-
Job job = new Job("Reconnect debugger") {
107+
Job job = new Job(Messages.ReconnectDebugJob) {
93108
@Override
94109
protected IStatus run(IProgressMonitor monitor) {
95110
try {
@@ -152,4 +167,53 @@ public void dispose() {
152167
super.dispose();
153168
}
154169

170+
@Override
171+
public void resetValidation() {
172+
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
173+
try {
174+
project.deleteMarkers(MARKER_TYPE, true, IResource.DEPTH_INFINITE);
175+
} catch (CoreException e) {
176+
MCLogger.logError("Failed to delete existing markers for the " + name + " project.", e);
177+
}
178+
}
179+
180+
@Override
181+
public void validationError(String filePath, String message, String quickFixId, String quickFixDescription) {
182+
validationEvent(IMarker.SEVERITY_ERROR, filePath, message, quickFixId, quickFixDescription);
183+
}
184+
185+
@Override
186+
public void validationWarning(String filePath, String message, String quickFixId, String quickFixDescription) {
187+
validationEvent(IMarker.SEVERITY_WARNING, filePath, message, quickFixId, quickFixDescription);
188+
}
189+
190+
private void validationEvent(int severity, String filePath, String message, String quickFixId, String quickFixDescription) {
191+
try {
192+
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
193+
IResource resource = project;
194+
if (filePath != null && !filePath.isEmpty()) {
195+
IPath path = new Path(filePath);
196+
if (filePath.startsWith(project.getName())) {
197+
path = path.removeFirstSegments(1);
198+
}
199+
IFile file = project.getFile(path);
200+
if (file != null && file.exists()) {
201+
resource = file;
202+
}
203+
}
204+
final IMarker marker = resource.createMarker(MARKER_TYPE);
205+
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
206+
marker.setAttribute(IMarker.LINE_NUMBER, 1);
207+
marker.setAttribute(IMarker.MESSAGE, message);
208+
if (quickFixId != null && !quickFixId.isEmpty()) {
209+
marker.setAttribute(CONNECTION_URL, mcConnection.baseUrl.toString());
210+
marker.setAttribute(PROJECT_ID, projectID);
211+
marker.setAttribute(QUICK_FIX_ID, quickFixId);
212+
marker.setAttribute(QUICK_FIX_DESCRIPTION, quickFixDescription);
213+
}
214+
} catch (CoreException e) {
215+
MCLogger.logError("Failed to create a marker for the " + name + " application: " + message, e);
216+
}
217+
}
218+
155219
}

dev/com.ibm.microclimate.core/src/com/ibm/microclimate/core/internal/MicroclimateApplication.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,18 @@ public void reconnectDebugger() {
203203
public void dispose() {
204204
// Override as needed
205205
}
206+
207+
public void resetValidation() {
208+
// Override as needed
209+
}
210+
211+
public void validationError(String filePath, String message, String quickFixId, String quickFixDescription) {
212+
// Override as needed
213+
}
214+
215+
public void validationWarning(String filePath, String message, String quickFixId, String quickFixDescription) {
216+
// Override as needed
217+
}
206218

207219
@Override
208220
public String toString() {

dev/com.ibm.microclimate.core/src/com/ibm/microclimate/core/internal/connection/MicroclimateConnection.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,40 @@ public void requestProjectBuild(MicroclimateApplication app, String action)
368368
HttpUtil.post(url, buildPayload);
369369
}
370370

371+
public void requestValidate(MicroclimateApplication app) throws JSONException, IOException {
372+
URI url = baseUrl.resolve(MCConstants.APIPATH_VALIDATE);
373+
374+
JSONObject buildPayload = new JSONObject();
375+
buildPayload.put(MCConstants.KEY_PROJECT_ID, app.projectID);
376+
buildPayload.put(MCConstants.KEY_PROJECT_TYPE, app.projectType.internalType);
377+
378+
HttpResult result = HttpUtil.post(url, buildPayload);
379+
if (!result.isGoodResponse) {
380+
final String msg = String.format("Received bad response from server %d with error message %s", //$NON-NLS-1$
381+
result.responseCode, result.error);
382+
throw new IOException(msg);
383+
}
384+
}
385+
386+
public void requestValidateGenerate(MicroclimateApplication app) throws JSONException, IOException {
387+
URI url = baseUrl.resolve(MCConstants.APIPATH_VALIDATE_GENERATE);
388+
389+
JSONObject buildPayload = new JSONObject();
390+
buildPayload.put(MCConstants.KEY_PROJECT_ID, app.projectID);
391+
buildPayload.put(MCConstants.KEY_PROJECT_TYPE, app.projectType.internalType);
392+
buildPayload.put(MCConstants.KEY_AUTO_GENERATE, true);
393+
394+
HttpResult result = HttpUtil.post(url, buildPayload);
395+
if (!result.isGoodResponse) {
396+
final String msg = String.format("Received bad response from server %d with error message %s", //$NON-NLS-1$
397+
result.responseCode, result.error);
398+
throw new IOException(msg);
399+
}
400+
401+
// Perform validation again to clear the errors/warnings that have been fixed
402+
requestValidate(app);
403+
}
404+
371405
public boolean isConnected() {
372406
return isConnected;
373407
}

dev/com.ibm.microclimate.core/src/com/ibm/microclimate/core/internal/connection/MicroclimateSocket.java

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Set;
1717

1818
import org.eclipse.osgi.util.NLS;
19+
import org.json.JSONArray;
1920
import org.json.JSONException;
2021
import org.json.JSONObject;
2122

@@ -62,7 +63,8 @@ public class MicroclimateSocket {
6263
EVENT_PROJECT_RESTART = "projectRestartResult", //$NON-NLS-1$
6364
EVENT_PROJECT_CLOSED = "projectClosed", //$NON-NLS-1$
6465
EVENT_PROJECT_DELETION = "projectDeletion", //$NON-NLS-1$
65-
EVENT_CONTAINER_LOGS = "container-logs"; //$NON-NLS-1$
66+
EVENT_CONTAINER_LOGS = "container-logs", //$NON-NLS-1$
67+
EVENT_PROJECT_VALIDATED = "projectValidated"; //$NON-NLS-1$
6668

6769
public MicroclimateSocket(MicroclimateConnection mcConnection) throws URISyntaxException {
6870
this.mcConnection = mcConnection;
@@ -207,6 +209,19 @@ public void call(Object... arg0) {
207209
MCLogger.logError("Error parsing JSON: " + arg0[0].toString(), e); //$NON-NLS-1$
208210
}
209211
}
212+
})
213+
.on(EVENT_PROJECT_VALIDATED, new Emitter.Listener() {
214+
@Override
215+
public void call(Object... arg0) {
216+
MCLogger.log(EVENT_PROJECT_VALIDATED + ": " + arg0[0].toString()); //$NON-NLS-1$
217+
218+
try {
219+
JSONObject event = new JSONObject(arg0[0].toString());
220+
onValidationEvent(event);
221+
} catch (JSONException e) {
222+
MCLogger.logError("Error parsing JSON: " + arg0[0].toString(), e); //$NON-NLS-1$
223+
}
224+
}
210225
});
211226

212227
socket.connect();
@@ -388,6 +403,51 @@ private void onLogUpdate(JSONObject event) throws JSONException {
388403
}
389404
}
390405
}
406+
407+
private void onValidationEvent(JSONObject event) throws JSONException {
408+
String projectID = event.getString(MCConstants.KEY_PROJECT_ID);
409+
MicroclimateApplication app = mcConnection.getAppByID(projectID);
410+
if (app == null) {
411+
MCLogger.logError("No application found for project: " + projectID);
412+
return;
413+
}
414+
app.resetValidation();
415+
416+
String status = event.getString(MCConstants.KEY_VALIDATION_STATUS);
417+
if (MCConstants.VALUE_STATUS_SUCCESS.equals(status)) {
418+
// Nothing to do
419+
return;
420+
}
421+
422+
if (event.has(MCConstants.KEY_VALIDATION_RESULTS)) {
423+
JSONArray results = event.getJSONArray(MCConstants.KEY_VALIDATION_RESULTS);
424+
for (int i = 0; i < results.length(); i++) {
425+
JSONObject result = results.getJSONObject(i);
426+
String severity = result.getString(MCConstants.KEY_SEVERITY);
427+
String filename = result.getString(MCConstants.KEY_FILENAME);
428+
String filepath = result.getString(MCConstants.KEY_FILEPATH);
429+
String type = null;
430+
if (result.has(MCConstants.KEY_TYPE)) {
431+
type = result.getString(MCConstants.KEY_TYPE);
432+
}
433+
String details = result.getString(MCConstants.KEY_DETAILS);
434+
String quickFixId = null;
435+
String quickFixDescription = null;
436+
if (result.has(MCConstants.KEY_QUICKFIX)) {
437+
JSONObject quickFix = result.getJSONObject(MCConstants.KEY_QUICKFIX);
438+
quickFixId = quickFix.getString(MCConstants.KEY_FIXID);
439+
quickFixDescription = quickFix.getString(MCConstants.KEY_DESCRIPTION);
440+
}
441+
if (MCConstants.VALUE_SEVERITY_WARNING.equals(severity)) {
442+
app.validationWarning(filepath, details, quickFixId, quickFixDescription);
443+
} else {
444+
app.validationError(filepath, details, quickFixId, quickFixDescription);
445+
}
446+
}
447+
} else {
448+
MCLogger.log("Validation event indicates failure but no validation results,"); //$NON-NLS-1$
449+
}
450+
}
391451

392452
boolean blockUntilFirstConnection() {
393453
final int delay = 100;

dev/com.ibm.microclimate.core/src/com/ibm/microclimate/core/internal/constants/MCConstants.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ private MCConstants() {}
2525
// Portal API endpoints
2626
APIPATH_PROJECT_LIST = "api/v1/projects",
2727
APIPATH_ENV = "api/v1/environment",
28+
APIPATH_VALIDATE = "api/v1/validate",
29+
APIPATH_VALIDATE_GENERATE = "api/v1/validate/generate",
2830
APIPATH_RESTART = "restart",
2931
APIPATH_BUILD = "build",
3032
APIPATH_CLOSE = "close",
@@ -33,7 +35,7 @@ private MCConstants() {}
3335
// JSON keys
3436
KEY_PROJECT_ID = "projectID",
3537
KEY_NAME = "name",
36-
// KEY_PROJECT_TYPE = "projectType",
38+
KEY_PROJECT_TYPE = "projectType",
3739
KEY_BUILD_TYPE = "buildType",
3840
KEY_LOC_DISK = "locOnDisk",
3941
KEY_CONTEXTROOT = "contextroot",
@@ -69,6 +71,26 @@ private MCConstants() {}
6971
VALUE_ACTION_BUILD = "build",
7072
VALUE_ACTION_ENABLEAUTOBUILD = "enableautobuild",
7173
VALUE_ACTION_DISABLEAUTOBUILD = "disableautobuild",
74+
75+
KEY_VALIDATION_STATUS = "validationStatus",
76+
KEY_VALIDATION_RESULTS = "validationResults",
77+
KEY_SEVERITY = "severity",
78+
KEY_FILENAME = "filename",
79+
KEY_FILEPATH = "filepath",
80+
KEY_TYPE = "type",
81+
KEY_LABEL = "label",
82+
KEY_DETAILS = "details",
83+
KEY_QUICKFIX = "quickfix",
84+
KEY_FIXID = "fixID",
85+
KEY_DESCRIPTION = "description",
86+
VALUE_STATUS_SUCCESS = "success",
87+
VALUE_STATUS_FAILED = "failed",
88+
VALUE_SEVERITY_ERROR = "error",
89+
VALUE_SEVERITY_WARNING = "warning",
90+
VALUE_TYPE_MISSING = "missing",
91+
VALUE_TYPE_INVALID = "invalid",
92+
93+
KEY_AUTO_GENERATE = "autoGenerate",
7294

7395
// JSON attribute values
7496
REQUEST_STATUS_SUCCESS = "success"

dev/com.ibm.microclimate.core/src/com/ibm/microclimate/core/internal/messages/Messages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public class Messages extends NLS {
7070
public static String BuildStateUnknown;
7171

7272
public static String DebugLaunchError;
73+
public static String ReconnectDebugJob;
7374

7475
static {
7576
// initialize resource bundle

dev/com.ibm.microclimate.core/src/com/ibm/microclimate/core/internal/messages/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@ BuildStateFailed=Build failed
6666
BuildStateUnknown=No build status information
6767

6868
DebugLaunchError=An error occurred trying to launch the debugger for the {0} project.
69+
ReconnectDebugJob=Reconnect debugger

dev/com.ibm.microclimate.ui/plugin.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@
9191
</or>
9292
</enablement>
9393
</actionProvider>
94+
<actionProvider
95+
id="com.ibm.microclimate.ui.microclimateApplicationActionProvider"
96+
class="com.ibm.microclimate.ui.internal.actions.MicroclimateApplicationActionProvider">
97+
<enablement>
98+
<or>
99+
<instanceof value="com.ibm.microclimate.core.internal.MicroclimateApplication" />
100+
</or>
101+
</enablement>
102+
</actionProvider>
94103
</navigatorContent>
95104
</extension>
96105

@@ -228,5 +237,11 @@
228237
<selection class="org.eclipse.core.resources.IResource"/>
229238
</wizard>
230239
</extension>
240+
241+
<extension point="org.eclipse.ui.ide.markerResolution">
242+
<markerResolutionGenerator
243+
markerType="com.ibm.microclimate.core.validationMarker"
244+
class="com.ibm.microclimate.ui.internal.marker.MicroclimateMarkerResolutionGenerator"/>
245+
</extension>
231246

232247
</plugin>

0 commit comments

Comments
 (0)