What are differences between Actions and Commands in the context of Eclipse RCP? I know that they both contribute to the menu entries, but which one is better? And why?
Of all the online resources I read, I could not get a firm understanding of the differences between both. I have not actually tried to use them, but just wanted to understand them to start with from higher level point of view.
Thanks
Did you read the eclipse wiki FAQ What is the difference between a command and an action?
You probably already understand that Actions and Commands basically do the same thing: They cause a certain piece of code to be executed. They are triggered, mainly, from artificats within the user interface
The main concern with Actions is that the manifestation and the code is all stored in the Action.
Although there is some separation in Action Delegates, they are still connected to the underlying action. Selection events are passed to Actions so that they can change their enabled state (programmatically) based on the current selection. This is not very elegant. Also to place an action on a certain workbench part you have to use several extension points.
Commands pretty much solve all these issues. The basic idea is that the Command is just the abstract idea of some code to be executed. The actual handling of the code is done by, well, handlers. Handlers are activated by a certain state of the workbench. This state is queried by the platform core expressions. This means that we only need one global Save command which behaves differently based on which handler is currently active.
This article details the differences
Actions:
The UI and handling are always tied. There is no way you can separate each other
While Actions can be contributed to different parts of the workbench (popup menu/tool bar), all of them were different extension points and so you end up duplicating the XML in multiple places. The worst of it is that not all the extension points expect the same configuration.
Specifying Actions in multiple places is a maintenance nightmare. If you have to change the icon of an action, you need to change in all the places.
Another issue with duplicating Actions in plugin.xml is that multiple instance of the same Actions will be created in the memory.
Commands involve more extension points, but:
Handler can be declared separately from a Command. This enables for multiple handler declarations for the same command.
The activeWhen for all the handlers are evaluated and the one that returns true for the most specific condition is selected. All these things are done without even loading your handler in the memory. Even without loading your plugin!
Defining the parameters is all about returning a map of display names & the ids. The name would be displayed in the key bindings page and the id would be used to invoke the command when the key sequence is pressed.
Define an IExecutionListener, which is merely an observer of the command execution so it can neither veto on it nor make any changes to the event
Just adding to VonC's excellent answer, commands might be a little overkill if your application is relatively small. They are relatively harder to setup, and they shine the most when you have multiple perspectives, editors and views.
For something simple, I would go with actions.
And remember that Action may be deprecated on later version of Eclipse. I'd suggest you to use Command from the beginning.
Related
I have a Feature file and the background step is pretty simple. However, the setup done in that step needs to be working with two different types of values and it is applicable to all the scenarios within that FF. Is there a way we can make this background dynamic?
Example: I want to do as below:
Background:
Given hospital configuration is done using '<some config>'
|some config|
| abc |
|xyz |
There are three ways I can think of to run a feature file twice, one with one configuration and the other with another configuration.
Duplicate the feature file and change the background so that it specifically loads the particular configuration.
Before dismissing this solution look at some of the positives.
its very simple
its easy to document (just put comments in the preamble about the duplication)
it supports customization specific to a particular profile.
The last point is worth expanding on. If the behavior is identical with each profile then what is the point of the profile. Basically you are saying it has no effect at all. If it has not effect at all then why are you testing it. If the behavior varies between profiles then you really want to explore and express those differences.
Run the feature twice by using an external setting.
This basically comes down to having Cucumber pull the setting from the environment and running cucumber twice, once for the first setting, and then again for the second setting.
So something like
SETTING=abc cucumber ...
SETTING=xyz cucumber ...
Use an around hook to run the internals of a scenario twice.
Here you are putting a tag on the feature and making a custom hook to run the scenarios twice. This is equivalent to the second solution but you are embedding the mechanism inside a single run of the features.
In ruby this would look something like
# run_twice_hook.rb
Around(#run_twice) do |scenario, block|
load_first_setting
block.call
load_second_setting
block.call
end
I think this solution comes closest to what the OP wants.
I also think this is the worst solution, because its technical, tricky, hidden and embedded inside the feature run. Its expensive to implement and expensive to maintain, and it probably hides an underlying business problem (mentioned in the first solution)
So please use this solution with a great deal of caution. In general with cuking simple is best, and a bit of repetition is preferable to technical complexity to avoid repetition.
I have a class (Android Activity) which handles start-up of my application. The application has some pretty complex start-up rules. Right now it looks like a bunch of spaghetti and I'm looking for strategies for refactoring it.
It's honestly such a mess I'm having problems hacking it down to provides pseudo code. In general there are some rules for start-up that are basically codified in logic:
Steps:
Check for error on last exit and flush local cache if necessary
Download settings file
Parse settings and save settings to local native format
Using the values in settings, do a bunch of 'house keeping'
Using a value in settings, download core data component A
Parse component A and load up local cache
During this logic, its also updating the user interface. All of this is handled in a zig-zagging, single monolithic class. Its very long, its got a bunch of dependencies, the logic is very hard to follow and it seems to touch way too many parts of the application.
Is there a strategy or framework that can be used to break up procedural start-up code?
Hmmm. Based on your steps, I see various different "concerns":
Reading and saving settings.
Downloading settings and components (not sure what a "component" is here) from the server.
Reading and instantiating components.
Flush and read cache.
Housekeeping (not really sure what this all entails).
UI updates (not really sure what this requires either).
You might try splitting up the code into various objects along the lines of the above, for example:
SettingsReader
ServerCommunicationManager (?)
ComponentReader
Cache
Not sure about 5 and 6, since I don't have much to go on there.
Regarding frameworks, well, there are various ones such as the previously mentioned Roboguice, that can help with dependency injection. Those may come in handy, or it may be easier just to do this by hand. I think that before you consider dependency injection, though, you need to untangle the code. All that dependency injection frameworks do is to initialize your objects for you -- you have to make sure that the objects make sense first.
Without any more details, the only suggestion that I can think of is to group the various steps behind well structured functions which do one thing and one thing only.
Your 6 steps look to be a good start for the 6 functions your init function should have. If #2 was synchronous (I doubt it), I would merge #2, #3 into a getSettings function.
I have encountered with this problem often. Couldn't think of a way to how to face this. Now I got this excellent forum!! I'm sure experts here will help me with this.
This is not a problem about a specific code segment like thing. I am capable (as I think) of doing some advance projects in java. It means, simply, I can finish the project to give the exact result.
But the problem is, though I can finish it some how, I'm not satisfied with the management of the classes etc. Actually I don't know how to properly manage it. I'll explain considering the project I'm currently working on (I'm not a professional coder, this will be for my self learning).
I'm working on a database management system (MySQL + Java). There I'm hoping to implement several features there. The flow will be, roughly, like this.
1. Login
2. Main window
Main window will be like this.
In the left panel you can select what you need to do.
Eg.
*. Add some entries to the database
*. Search database
*. Other..(will be add later)
Can some one please tell me how to manage all those things, two frames and several panels.
What I've done is like this.
I've written a managerClass which has the main method. Then It'll call loginFrame first. After validation, loginFrame calls a method in managerClass, to load mainFrame. But I keep a reference to the managerClass in all the frames, panels etc.. as I save all the required info in managerClass, like user name ect..
But when modifying and debugging, things become really really difficult. As I haven't done thing according to any specific rule. I'll have to modify almost all the classes to do a slight modification. I've though a lot and sea
From what I can understand of your application, your main issue is the coupling between your components and the different layers of the application (presentation, interaction control, domain logic). I would suggest using two design patterns (or styles) that may help here:
Model-View-Presenter: separates the Model/Domain logic from the presentation (View) from the logic of controlling user interactions. I've used it recently in a large application and I've found it really helps to separate concerns in a clean way and makes testing much more simple. Please don't confuse it with the Model-View-Controller model, which is close, but have many issues. There's a nice article by Martin Fowler describing these two patterns
Adopt an event based interaction between your components. Instead of the Login frame calling the Manager class, make it fire an event ("user authenticated"), which is handle by the interested components. For example, you may have a small user account details panel in the main window which is not displayed until this event is triggered. Unfortunately, I'm not aware of any event framework for plain Java (which I suspect if the what you are using for development) The one I use is for Google Web Toolkit.
I have a JAR-packaged standalone application that, when executed, unpacks itself into a temporal directory and spawns a child process within that directory. The reason being some third-party code and configuration assumes data files are found relative to current working directory, and java has no chdir() method, so the only way is to switch the working dir for a child process.
All works fine, except for the system properties. An operator may decide to specify some system properties in the command line, both standard ones and ones related to the third-party configuration:
java -Djava.io.tmpdir=/temp -Dsomething=else -jar foo.jar (parameters)
The system properties available to the parent java process are not by default propagated to child. I should do it myself. And here I get into a roadblock: I have no way to tell which properties are set by operator and which are initialized by default by JVM.
Take that java.io.tmpdir one. If operator has provided it, he has a good reason to do so (perhaps the default location is "disk full"). I have to set it to child process, or it will fail. But how do I know if it came from operator? It may be just the default value.
I may try and set all available system properties to the child process. It takes a long list though and, worse, fails in some environments where the command line length is limited.
The only workaround I've found so far (quite a wicked one) is to spawn another child process first, with no arguments at all, and let it pipe back to the parent all the system properties it has. The values that match those that parent has are defaults. The rest should be passed down to the worker child process.
Does anyone have a better alternative?
Where I work, we had a slowly growing list of system properties that users could apply, and while we did not have the child process to worry about, we did have a different issue: there were simply too many.
Rather than making the user supply system properties via the command line (or, in our case, making the line in the script that launches the application yet another property longer), we added support for loading a .properties file by default.
If you can convince users to put permanent properties there, then start the process of launching the child process, and then loading from the file, you could avoid the headache altogether.
Still, you would likely be presented with debug scenarios where temporary, or one-time properties are desired without modifying the file (not that it's really a big deal). You have a few choices here:
Continue to use the approach you are currently.
Get the user to pass the system properties as command line arguments that you then load into system properties for both the parent and child process.
Say tough, use the file. (Not a terrible thing, but I would be annoyed with that solution as a user)
I don't think there is a good answer to this. But fortunately, most of the standard system properties either can't be overridden, or nobody in their right mind would override.
So the following approaches are probably your best bets:
pass on the subset of the standard properties that you think that it makes sense to pass on,
provide a way to specify the JVM options (including -D options) to be used for child JVMs, or
a combination of the above approaches.
Chosen solution:
I still had to go with a child process that does nothing but passes the parent all the system properties it gets to compare. The only minor issue I stumbled upon was line.separator property which caused my line reading code stumble on extra empty line. That was easy to fix.
Why I accepted none of answers:
Approaches suggested in the answers below are reasonable, but none of them is completely satisfying.
I do not have much power over the users to tell them that Java system properties should be passed via a property file or a special command-line argument. This is awkward and goes against operational practices (special cases are always bad).
I cannot also select a subset of system properties to pass to the child process. System class documentation doesn't tell which ones are OK to overwrite (and common sense replaces no documentation). There is also a facility for end-user to define their own properties, and those I cannot predict neither by name no number.
I made up an applet to auto dial a contacts number via our phone system switchvox, as well as log the call information into our CRM, salesforce. The issue I am running into is that unless I use the separate JVM parameter things get screwy.
For example say they have multiple tabs open for multiple contacts, thus multiple applets running in the same jvm. Without the separate jvm parameter sometimes it will dial a number from another tab. I pass the number via the parameter tags and I have even tried passing the number by calling a JS method from the applet with still no luck.
Since our crm is cloud based people like to have multiple tabs open, but do not like seeing multiple java icons down below, go figure. Anybody have this issue before, and/or have a workaround without the separate jvms.
It is hard to say without looking at your applet's code.
But I would hazard a guess that your code is putting some of its mutable state in statics, and occasionally one instance of the applet is interfering with another via the statics.
If you have any shared mutable statics in your applet, ideally you should get rid of them. Or if the state really needs to be shared by multiple instances of the applet, make sure that all accesses are properly synchronized.
Statics are shared among the applets since they're all running in the same VM. You could try the classloader_cache="false" applet option and still share the VM. I am not sure whether this option applies only on applet startup, however, as I haven't had success with it working all the time.
The best bet is to get rid of statics or use separate_jvm.