Binding keys using org.eclipse.ui.binding - eclipse-plugin

I am trying to introduce a shortcut key(Ctrl+Shift+f) to our customized editor to format the content.
I've implememented the following changes.
Added changes to plugin xml by adding key extension with definition Id/schema/context.
Implemented Action by extending TextEditorAction class as below.
#Override
public void run() {
this.doOperation(ISourceViewer.FORMAT);
}
Implemented one Formatter class by implementing IContentFormatter.
Passed the above Formatter class to our cutsomized sourceVIewConfiguration (extends SourceViewerConfiguration) class by overriding getContentFormatter.
overrided createActions() API inside our customized editor class which extends TextEditor.
For some reason my shortcut key is not working. I put a debug point inside my action class and noticed the controller is not going there when i press on the shortcut key.
I also noticed that the newly created key is not displayed under preferences -> keys list.
Can somebody provide pointers or example to resolve the issue.
plugin.xml entries:
<key
commandId="com.language.javascripteditor.XJSFormatAction"
schemeId="myScheme"
sequence="M1+M2+z"/>
<scheme
id="myScheme"
name="myScheme">
</scheme>
Formatter class:
public class JavaScriptEditorFormatter implements IContentFormatter {
#Override
public void format(IDocument document, IRegion region) {
try {
String content =document.get(region.getOffset(), region.getLength());
String formatted = new JSBeautifier().js_beautify(content,null);
document.replace(region.getOffset(), region.getLength(), formatted);
} catch (BadLocationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
#Override
public IFormattingStrategy getFormattingStrategy(String contentType) {
throw new UnsupportedOperationException();
}
}
Added a new property file for customized schema with the name plugin_customization.ini and with the content as below
org.eclipse.ui/KEY_CONFIGURATION_ID=myScheme
Command section inside plugin.xml
<command
defaultHandler="com.cisco.nm.workflowbuilder.language.javascripteditor.XJSFormatAction"
id="com.language.javascripteditor.XJSFormatAction"
name="%action.label.format.xjs">
</command>
Instead of a handler I have written an Action class. Please let me know if this approach does not work

1.Added contributor class to extension of the existing editor.
2.Created command with an id for format.eg: com.javascript.text.format
3.written Action class with format method
#Override
public void run() {
this.doOperation(ISourceViewer.FORMAT);
}
4. plugin xml entry
<key
commandId="com.javascript.text.format"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="M1+M2+F"/>
5. Overriden the createActions() .Inside this method instantiated the Action class and setActionDefinitionId.

Related

How to remove Startup/Configuration tab from Intellij Plugin extending RunConfigurationBase

I am creating a custom IntelliJ plugin (following the IntelliJ tutorial) that implements a custom Run Configuration. My plugin will "run" the contents the open file in the editor on a remote server and display the result in IntelliJ (sort of a script playground). I used the IntelliJ GUI Designer to create the form and it shows up in the Edit Run Configuration, however it shows up under 2 tabs (Configuration and Startup/Configuration) .. neither of which I explicitly define, I assume they come from my extending of RunConfigurationBase?.
public class RunConfigurationImpl extends RunConfigurationBase {
public RunConfigurationImpl(Project project, ConfigurationFactory factory, String name) {
super(project, factory, name);
}
#NotNull
#Override
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
return new SettingsEditorImpl();
}
#Nullable
#Override
public SettingsEditor<ConfigurationPerRunnerSettings> getRunnerSettingsEditor(ProgramRunner runner) {
return null;
}
#Override
public void checkConfiguration() throws RuntimeConfigurationException {
}
#Nullable
#Override
public RunProfileState getState(#NotNull Executor executor, #NotNull ExecutionEnvironment executionEnvironment) throws ExecutionException {
return null;
}
}
The first tab is fine (Configuration) ..
However I do not want to list the same fields again on the Startup/Connection tab, in fact, I'm happy to just do away with this tab -- or really, I don't care which tab I get rid off, I just
want the fields to show once.
Any pointers on how to get rid of this tab?
See com.intellij.execution.configurations.RunConfiguration#getRunnerSettingsEditor It returns null by default so let it stay null, don’t override it.
This is a consolidation of Vassiliy's answer and ensuing comments.
In order to remove the Startup/Connection tab in the custom Run Configuration UI, ensure that null is being returned from the methods getRunnerSettingsEditor() custom the classes that extends com.intellij.execution.configurations.RunConfiguration and com.intellij.execution.runners.ProgramRunner
By default the API abstract classes return null for these methods, so make sure you are not overriding them.

How to register ORMObjectListener in Intershop7

We have implemented several custom ORM objects in our webshop implementation that have references (dependencies) to Intershop Product system object.
When a user tries to delete a certain product in back-office, it causes problems because references to that product may still exist in our custom objects. Naturally, deleting a product that is referenced from one of our custom objects generates an exception like this:
java.sql.SQLTransactionRollbackException: ORA-02091: transaction rolled back ORA-02292: integrity constraint (INTERSHOP.A1POSTPAIDPRICE_CO_002) violated - child record found
We have figured that we could solve that by implementing an ORMObjectListener and overriding objectDeleting method to delete all the references before the product actually gets deleted.
Intershop cookbook for ORM layer states:
"Instances must implement the interface ORMObjectListener for a given ORM object type and register at the factory. The listener is called when instances of the given type are created, changed or removed."
(https://support.intershop.com/kb/index.php/Display/2G3270#Cookbook-ORMLayer-Recipe:NotificationofPersistentObjectChanges)
However, we cannot find a cookbook for registering the listener at the factory. What do we need to do to register the listener?
Also, if there is some better way for handling dependencies to system objects on our custom objects during delete event, I'm open to suggestions.
UPDATE:
This is the listener class I have tried with so far:
public class ProductDeleteListener implements ORMObjectListener<ProductPO> {
#Inject
ProductPOFactory productPOFactory;
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(ProductDeleteListener.class);
public ProductDeleteListener() {
productPOFactory.addObjectListener(this, new AttributeDescription[0]);
}
#Override
public boolean isOldStateNeeded() {
// TODO Auto-generated method stub
return false;
}
#Override
public void objectChanged(ProductPO object, Map<AttributeDescription, Object> previousValues) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("PRODUCT LISTENER TEST - CHANGE");
}
}
#Override
public void objectChanging(ProductPO object, Map<AttributeDescription, Object> previousValues) {
// TODO Auto-generated method stub
}
#Override
public void objectCreated(ProductPO object) {
// TODO Auto-generated method stub
}
#Override
public void objectCreating(ProductPO object) {
// TODO Auto-generated method stub
}
#Override
public void objectDeleted(ORMObjectKey objectKey) {
// TODO Auto-generated method stub
}
#Override
public void objectDeleting(ProductPO object) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("PRODUCT LISTENER TEST - PRE DELETE");
}
}
}
But it is not working. Nothing gets logged when object changes or gets deleted.
In addition to what Willem Evertse wrote you need to place your registration code in a class that gets instantiated via Intershop Component Framework.
implementation.component:
<components xmlns="http://www.intershop.de/component/2010" scope="global">
<implementation name="ProductDeleteListenerRegistrar"
class="your.fullqualifed.ProductDeleteRegistrar" start="start" stop="stop"></implementation>
instances.component:
<components xmlns="http://www.intershop.de/component/2010"> <instance name="ORMValidator" with="ORMValidator" scope="global"/></components>
You need to write a class, e.g. ProductDeleteRegistrar and provide start method in which you can add registration calls like Willem described. As for stop method you need to safely unregister your object listener. Make sure both methods are declared to be synchronized.
I think registering a listen would be the right approach. Maybe just look out for performance problems.
You are right that there are no examples of this, but here is an example.
Get the factory that you want to receive messages from. In your case, it is ProductPOFactory
ProductPOFactory productFactory = (ProductPOFactory) NamingMgr.getInstance().lookupFactory(ProductPO.class);
productFactory.addObjectListener(new MyProductChangeListener());
MyProductChangeListener needs to extend AbstractORMObjectListener<ProductPO>
and implement the method public void objectDeleting(T object)
Every time a product gets deleted your listener should be called and then you can clean up your custom orm objects. You can have a look at ImageSetDefinitionPOListener as an example

bytecode tools: add method interceptor to classes (not proxy)

Javassist proxyFactory can create proxy at runtime with method interceptor. But how to add method interceptor to a class statically by modifying the class file?
For example, class Foo has 100 methods, before calling any method on an instance of Foo, need to check if the Foo instance is initialized.
public class Foo {
public void methodA() {
...
}
public void methodB() {
...
}
public void methodC() {
...
}
....
}
How to modify the class file to add such method interceptor? One way is to add code at the beginning of each method. Is there a better way?
How about other bytecode tools such as cglib, ....?
There are two options with ByteBuddy to achive this:
use redefine/rebase feature - You can check the details on ByteBuddy tutorial under 'type redefinition'/'type rebasing' tags. Limitation here is that this kind of transformation needs to be done before a target class is loaded.
Java Agent - agents run before class is loaded so they are allowed to modify existing classes. ByteBuddy comes with nice AgentBuilder (tutorial - 'Creating Java agents'). There is also posiblity to install special ByteBuddy agent at runtime (example from mentioned tutorial).
class Foo {
String m() { return "foo"; }
}
class Bar {
String m() { return "bar"; }
}
ByteBuddyAgent.install();
Foo foo = new Foo();
new ByteBuddy()
.redefine(Bar.class)
.name(Foo.class.getName())
.make()
.load(Foo.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
assertThat(foo.m(), is("bar"));

Is there anyway to log after save with Spring Data Repository

I'm trying to logging some information after save entity with Spring Data Repository, is there anyway?
Thanks!
You can use Annotated repo event handlers.
Just add the #RepositoryEventHandler annotation to your handler class, than in this class implement the handler method with #HandleAfterCreate and #HandleAfterSave annotations.
#RepositoryEventHandler
public class EventHandler {
#HandleAfterCreate
#HandleAfterSave
public void handleAfterCreateOrSave(Entity e) {
// LOG...
}
}

How to develop this Eclipse plug-in: add a menu in the page "properties for XXXProject"

I'm going on developing an Eclipse plugin: collect a config for a project. I want to write a GUI for every project properties so that user can input every config item.
How can I implement it. I have researched for some days, just find a way to add a menu in Eclipse Preferences.
But I want to add menu to project properties. Like: User right-click the project in Eclipse, then click Properties, config menu is in left of the properties dialog.
What should I do?
You add to the properties tree by using the org.eclipse.ui.propertyPages extension point in your plugin.
An example property page declaration:
<extension
point="org.eclipse.ui.propertyPages">
<page
class="org.eclipse.ui.internal.ide.dialogs.ResourceInfoPage"
id="org.eclipse.ui.propertypages.info.file"
name="Resource"
>
<enabledWhen>
<adapt type="org.eclipse.core.resources.IResource"/>
</enabledWhen>
</page>
The above is the declaration of the Resource property page taken from Eclipse. It declares that the property page is provided by the ResourceInfoPage class and that it is only shown (enabled) when the selected object is an IResource (a project, folder or file).
The property page class that you write should extend the org.eclipse.ui.dialogs.PropertyPage class. so a skeleton class would be:
public class MyPropertyPage extends PropertyPage
{
#Override
protected Control createContents(Composite parent)
{
IAdaptable selectedObject = getElement();
Composite composite = new Composite(parent, SWT.NONE);
// TODO add your controls here
return composite;
}
#Override
public boolean performDefaults()
{
// TODO deal with Defaults button
}
#Override
public boolean performOk()
{
// TODO deal with OK button
}
}