Deactivate all Codan Checkers programmatically - eclipse-plugin

How can I deactivate all Codan Checkers for my content type or inside my editor programmatically?
I know I can turn off the Checkers in Window -> Preferences -> C/C++ -> Code Analysis. But I need to do that programmatically.
One way to achieve that is to modify the methods runInEditor() and processResource() in org.eclipse.cdt.codan.internal.core.CodanRunner.
public static void runInEditor(Object model, IResource resource, IProgressMonitor monitor) {
if (resource != null && !resource.toString().endsWith("blub)) {
processResource(resource, model, CheckerLaunchMode.RUN_AS_YOU_TYPE, monitor);
}
}
public static void processResource(IResource resource, CheckerLaunchMode checkerLaunchMode, IProgressMonitor monitor) {
if (resource != null && !resource.toString().endsWith("blub")) {
processResource(resource, null, checkerLaunchMode, monitor);
}
}
For the Unresolved Inclusion warning I can overwrite CPreprocessor and return do nothing in the overriden handleProblem() method.
Is there a way to suppress the Codan Checkers without modifying CDT code?

You should be able to do this using the org.eclipse.cdt.codan.core.checkerEnablement extension point.
I can't find generated documentation for it, but you can see the schema for it here.
The extension point allows you to specify a class inheriting from org.eclipse.cdt.codan.internal.core.ICheckerEnablementVerifier and provide a method boolean isCheckerEnabled(IChecker, IResource, CheckerLaunchMode) which determines if the given checker can run on the given resource in the given launch mode. If any enablement verifier returns false, the checker is not run.
Register your own implementation of ICheckerEnablementVerifier in your Plugin's plugin.xml:
<extension
point="org.eclipse.cdt.codan.core.checkerEnablement">
<verifier class="path.to.MyCheckerEnablementVerifier" />
</extension>
The following implementation checks the content type:
public class MyCheckerEnablementVerifier implements ICheckerEnablementVerifier {
#Override
public boolean isCheckerEnabled(IChecker checker, IResource resource, CheckerLaunchMode mode) {
IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
IContentType contentType = contentTypeManager.findContentTypeFor(resource.getLocation().toOSString());
if (contentType.getId().equals("contenttypeid")) {
return false;
} else {
return true;
}
}
}

Related

How to persist/read-back Run Configuration parameters in Intellij plugin

I'm making a basic IntelliJ plugin that lets a user define Run Configuration (following the tutorial at [1]), and use said Run Configurations to execute the file open in the editor on a remote server.
My Run Configuration is simple (3 text fields), and I have it all working, however, after editing the Run Configuration, and click "Apply" or "OK" after changing values, the entered values are lost.
What is the correct way to persist and read-back values (both when the Run Configuration is re-opened as well as when the Run Configuration's Runner invoked)? It looks like I could try to create a custom persistence using [2], however, it seems like the Plugin framework should have a way to handle this already or at least hooks for when Apply/OK is pressed.
[1] https://www.jetbrains.org/intellij/sdk/docs/tutorials/run_configurations.html
[2] https://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html
Hopefully, this post is a bit more clear to those new to IntelliJ plugin development and illustrates how persisting/loading Run Configurations can be achieved. Please read through the code comments as this is where much of the explanation takes place.
Also now that SettingsEditorImpl is my custom implementation of the SettingsEditor abstract class, and likewise, RunConfigurationImpl is my custom implementation of the RunConfigiration abstract class.
The first thing to do is to expose the form fields via custom getters on your SettingsEditorImpl (ie. getHost())
public class SettingsEditorImpl extends SettingsEditor<RunConfigurationImpl> {
private JPanel configurationPanel; // This is the outer-most JPanel
private JTextField hostJTextField;
public SettingsEditorImpl() {
super();
}
#NotNull
#Override
protected JComponent createEditor() {
return configurationPanel;
}
/* Gets the Form fields value */
private String getHost() {
return hostJTextField.getText();
}
/* Copy value FROM your custom runConfiguration back INTO the Form UI; This is to load previously saved values into the Form when it's opened. */
#Override
protected void resetEditorFrom(RunConfigurationImpl runConfiguration) {
hostJTextField.setText(StringUtils.defaultIfBlank(runConfiguration.getHost(), RUN_CONFIGURATION_HOST_DEFAULT));
}
/* Sync the value from the Form UI INTO the RunConfiguration which is what the rest of your code will interact with. This requires a way to set this value on your custom RunConfiguration, ie. RunConfigurationImpl##setHost(host) */
#Override
protected void applyEditorTo(RunConfigurationImpl runConfiguration) throws ConfigurationException {
runConfiguration.setHost(getHost());
}
}
So now, the custom SettingsEditor, which backs the Form UI, is set up to Sync field values In and Out of itself. Remember, the custom RunConfiguration is what is going to actually represent this configuration; the SettingsEditor implementation just represents the FORM (a subtle difference, but important).
Now we need a custom RunConfiguration ...
/* Annotate the class with #State and #Storage, which is used to define how this RunConfiguration's data will be persisted/loaded. */
#State(
name = Constants.PLUGIN_NAME,
storages = {#Storage(Constants.PLUGIN_NAME + "__run-configuration.xml")}
)
public class RunConfigurationImpl extends RunConfigurationBase {
// Its good to 'namespace' keys to your component;
public static final String KEY_HOST = Constants.PLUGIN_NAME + ".host";
private String host;
public RunConfigurationImpl(Project project, ConfigurationFactory factory, String name) {
super(project, factory, name);
}
/* Return an instances of the custom SettingsEditor ... see class defined above */
#NotNull
#Override
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
return new SettingsEditorImpl();
}
/* Return null, else we'll get a Startup/Connection tab in our Run Configuration UI in IntelliJ */
#Nullable
#Override
public SettingsEditor<ConfigurationPerRunnerSettings> getRunnerSettingsEditor(ProgramRunner runner) {
return null;
}
/* This is a pretty cool method. Every time SettingsEditor#applyEditorTo() is changed the values in this class, this method is run and can check/validate any fields! If RuntimeConfigurationException is thrown, the exceptions message is shown at the bottom of the Run Configuration UI in IntelliJ! */
#Override
public void checkConfiguration() throws RuntimeConfigurationException {
if (!StringUtils.startsWithAny(getHost(), "http://", "https://")) {
throw new RuntimeConfigurationException("Invalid host");
}
}
#Nullable
#Override
public RunProfileState getState(#NotNull Executor executor, #NotNull ExecutionEnvironment executionEnvironment) throws ExecutionException {
return null;
}
/* This READS any prior persisted configuration from the State/Storage defined by this classes annotations ... see above.
You must manually read and populate the fields using JDOMExternalizerUtil.readField(..).
This method is invoked at the "right time" by the plugin framework. You dont need to call this.
*/
#Override
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
host = JDOMExternalizerUtil.readField(element, KEY_HOST);
}
/* This WRITES/persists configurations TO the State/Storage defined by this classes annotations ... see above.
You must manually read and populate the fields using JDOMExternalizerUtil.writeField(..).
This method is invoked at the "right time" by the plugin framework. You dont need to call this.
*/
#Override
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
JDOMExternalizerUtil.writeField(element, KEY_HOST, host);
}
/* This method is what's used by the rest of the plugin code to access the configured 'host' value. The host field (variable) is written by
1. when writeExternal(..) loads a value from a persisted config.
2. when SettingsEditor#applyEditorTo(..) is called when the Form itself changes.
*/
public String getHost() {
return host;
}
/* This method sets the value, and is primarily used by the custom SettingEditor's SettingsEditor#applyEditorTo(..) method call */
public void setHost(String host) {
this.host = host;
}
}
To read these configuration values elsewhere, say for example a custom ProgramRunner, you would do something like:
final RunConfigurationImpl runConfiguration = (RunConfigurationImpl) executionEnvironment.getRunnerAndConfigurationSettings().getConfiguration();
runConfiguration.getHost(); // Returns the configured host value
See com.intellij.execution.configurations.RunConfigurationBase#readExternal as well as com.intellij.execution.configurations.RunConfigurationBase#loadState and com.intellij.execution.configurations.RunConfigurationBase#writeExternal

Can Spring-Data-Rest handle associations to Resources on other Microservices?

For a new project i'm building a rest api that references resources from a second service. For the sake of client convenience i want to add this association to be serialized as an _embedded entry.
Is this possible at all? i thought about building a fake CrudRepository (facade for a feign client) and manually change all urls for that fake resource with resource processors. would that work?
a little deep dive into the functionality of spring-data-rest:
Data-Rest wraps all Entities into PersistentEntityResource Objects that extend the Resource<T> interface that spring HATEOAS provides. This particular implementation has a list of embedded objects that will be serialized as the _embedded field.
So in theory the solution to my problem should be as simple as implementing a ResourceProcessor<Resource<MyType>> and add my reference object to the embeds.
In practice this aproach has some ugly but solvable issues:
PersistentEntityResource is not generic, so while you can build a ResourceProcessor for it, that processor will by default catch everything. I am not sure what happens when you start using Projections. So that is not a solution.
PersistentEntityResource implements Resource<Object> and as a result can not be cast to Resource<MyType> and vice versa. If you want to to access the embedded field all casts have to be done with PersistentEntityResource.class.cast() and Resource.class.cast().
Overall my solution is simple, effective and not very pretty. I hope Spring-Hateoas gets full fledged HAL support in the future.
Here my ResourceProcessor as a sample:
#Bean
public ResourceProcessor<Resource<MyType>> typeProcessorToAddReference() {
// DO NOT REPLACE WITH LAMBDA!!!
return new ResourceProcessor<>() {
#Override
public Resource<MyType> process(Resource<MyType> resource) {
try {
// XXX all resources here are PersistentEntityResource instances, but they can't be cast normaly
PersistentEntityResource halResource = PersistentEntityResource.class.cast(resource);
List<EmbeddedWrapper> embedded = Lists.newArrayList(halResource.getEmbeddeds());
ReferenceObject reference = spineClient.findReferenceById(resource.getContent().getReferenceId());
embedded.add(embeddedWrappers.wrap(reference, "reference-relation"));
// XXX all resources here are PersistentEntityResource instances, but they can't be cast normaly
resource = Resource.class.cast(PersistentEntityResource.build(halResource.getContent(), halResource.getPersistentEntity())
.withEmbedded(embedded).withLinks(halResource.getLinks()).build());
} catch (Exception e) {
log.error("Something went wrong", e);
// swallow
}
return resource;
}
};
}
If you would like to work in type safe manner and with links only (addition references to custom controller methods), you can find inspiration in this sample code:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.RepresentationModelProcessor;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
#Configuration
public class MyTypeLinkConfiguration {
public static class MyType {}
#Bean
public RepresentationModelProcessor<EntityModel<MyType>> MyTypeProcessorAddLifecycleLinks(MyTypeLifecycleStates myTypeLifecycleStates) {
// WARNING, no lambda can be passed here, because type is crucial for applying this bean processor.
return new RepresentationModelProcessor<EntityModel<MyType>>() {
#Override
public EntityModel<MyType> process(EntityModel<MyType> resource) {
// add custom export link for single MyType
myTypeLifecycleStates
.listReachableStates(resource.getContent().getState())
.forEach(reachableState -> {
try {
// for each possible next state, generate its relation which will get us to given state
switch (reachableState) {
case DRAFT:
resource.add(linkTo(methodOn(MyTypeLifecycleController.class).requestRework(resource.getContent().getId(), null)).withRel("requestRework"));
break;
case IN_REVIEW:
resource.add(linkTo(methodOn(MyTypeLifecycleController.class).requestReview(resource.getContent().getId(), null)).withRel("requestReview"));
break;
default:
throw new RuntimeException("Link for target state " + reachableState + " is not implemented!");
}
} catch (Exception ex) {
// swallowed
log.error("error while adding lifecycle link for target state " + reachableState + "! ex=" + ex.getMessage(), ex);
}
});
return resource;
}
};
}
}
Note, that myTypeLifecycleStates is autowired "service"/"business logic" bean.

Getting Tab parameters inside LaunchConfigurationDelegate

I have a custom launch configuration. It currently has a JavaArgumentsTab() where I can enter things for VM arguments and Program arguments. But how do I actually get any values entered there?
Ideally I would get them inside my LaunchConfigurationDelegate's launch() method. I expected to find any text entered as arguments inside the LaunchConfiguration or other parameters to that method, and I'm sure this is a newbie question, but I really haven't found anything promising.
TabGroup:
public class LaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup {
#Override
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
new JavaArgumentsTab(),
new CommonTab()
};
setTabs(tabs);
} }
LaunchConfigurationDelegate:
public class LaunchConfigurationDelegate implements ILaunchConfigurationDelegate {
#Override
public void launch(ILaunchConfiguration configuration, String mode,
ILaunch launch, IProgressMonitor monitor) throws CoreException {
// How to get anything entered on my Java tab here...?
} }
Everything from the tabs should already have been set as attribute values in the ILaunchConfiguration when launch is called.
The settings from JavaArgumentsTab are stored in the attributes using constants from IJavaLaunchConfigurationConstants.

How does HiveInterruptUtils.interrupt() work?

I've been reading the hive source code recently, but I'm confused by this interrupt(). I want to know how it interrupts the current hive command.The location of this function is in CliDriver.processLine().
In the implementation of HiveInterruptUtils http://people.apache.org/~hashutosh/hive-clover/common/org/apache/hadoop/hive/common/HiveInterruptUtils.html, find this:
public static void interrupt() {
synchronized (interruptCallbacks) {
for (HiveInterruptCallback resource :
new ArrayList<HiveInterruptCallback>(interruptCallbacks)) {
resource.interrupt();
}
}
}
That might interrupts all resources previously added to the HiveInterruptCallback list.
And also the HiveInterruptCallback, http://people.apache.org/~hashutosh/hive-clover/common/org/apache/hadoop/hive/common/HiveInterruptCallback.html#HiveInterruptCallback, is an interface.
public interface HiveInterruptCallback {
/**
* Request interrupting of the processing
*/
void interrupt();
}
The previously registered resources implement HiveInterruptCallback interrupt() method, so the HiveInterruptUtils.interrupt() behavior depends on the specific resource implementation.

Activating find/replace for jface TextViewer eclipse worbench action

I have made an eclipse plugin with TextViewer interface for displaying a text document but the standard find/replace stay in gray mode.
I assume you are using the TextViewer in a view rather than an editor. In this case:
Your view in which the TextViewer is used must "adapt" to org.eclipse.jface.text.IFindReplaceTarget i.e. its getAdapter() must return the target from viewer.
You need to explicitly register a handler for "org.eclipse.ui.edit.findReplace" command (which can be org.eclipse.ui.texteditorFindReplaceAction). Check out Platform Command Framework to get started.
I've used Martii Käärik's pointers for finding the answer to this question. I've got it working with the following code, which however uses an internal string identifier from TextEditor. Still, here it goes.
getAdapter() in the view must be implemented like this (viewer is an instance of TextViewer)
public Object getAdapter(Class adapter) {
if (IFindReplaceTarget.class.equals(adapter)) {
if (viewer != null) {
return viewer.getFindReplaceTarget();
}
}
return super.getAdapter(adapter);
}
In createPartControl() of your view, add this code:
FindReplaceAction findAction= new FindReplaceAction(ResourceBundle.getBundle("org.eclipse.ui.texteditor.ConstructedTextEditorMessages"), null, this);
IHandlerService handlerService= (IHandlerService) getSite().getService(IHandlerService.class);
IHandler handler= new AbstractHandler() {
public Object execute(ExecutionEvent event) throws ExecutionException {
if (viewer != null && viewer.getDocument() != null)
findAction.run();
return null;
}
};
handlerService.activateHandler("org.eclipse.ui.edit.findReplace", handler);
No XML required.