Limiting contributed extension point data between plugins - eclipse

I have 2 eclipse plugins that I am building; let's call them plugin A and plugin B...
Plugin A requires a license to run and Plugin B is free to the world. I have created an extension point in Plugin B to which Plugin A contributes (and in some cases overrides) data. I would like to find a way to disregard that data in plugin B if plugin A is not licensed (without have to check to see if the plugin can start).
Is there such a mechanism in eclipse that allows me to accomplish such a feat? My current workaround is to check to see if the plugin is started (via the Bundle) and if it isn't attempt to start it. If the plugin A is unlicensed I throw an exception in the start() method.

Shouldn't A check its license itself and not-override/not-contribute any data (or override with providing identical data) if it is not licensed? Why place the burden of license checking on B when essentially B doesn't care (as it's free).
I'd opt for A to start in a limited mode if the license is not found. You might also - as jamesh suggested - want to give the user the opportunity to provide the license, e.g. with an additional A-UI plugin informing the user about the missing license and offering to license.

Requirements
So, you are writing two plugins.
Plugin B has an extension point. If the user has the bundle for Plugin A, and the license, then plugin A should contribute extensions to the EP in plugin B.
Approaches
OSGi's security model is largely built atop the default Java Permissions and SecurityManager. There is a discussion in this presentation from Apache Felix. I expect it would be possible to build a licensing scheme around this.
You're workaround sounds like it could work, however, there are a couple of concerns:
stopping a bundle from starting may prevent any services being registered, but will it effect a change in the extension registry? i.e. those extensions registered using plugin.xml. I would guess that DS services would be ok, but I'd have to try it.
stopping the bundle may not be enough - can it be started again later on? I would probably want it UNINSTALLED.
an unlicensed bundle is an opportunity telling the user about licensing. So, how do you tell the user that the bundle was not licensed, and won't be able to be used, and btw, here's how you license it.
So far you haven't said anything about how the license is to be implemented. I'm guessing you'll go for a LicenseService, or even perhaps a singleton.
Do report back what you find.

One possible solution I can think of is that you contribute a class from plugin A to Plugin B. Then, when plugin B reads the contribution items, it can try to create an instance of this class.
The class, from plugin A, can then throw some exception in the constructor if it is not licensed. This will tell plugin B that the information from plugin A can be disregarded.
A possible implementation in plugin B can look like this:
IExtensionPoint extensionPoint = registry.getExtensionPoint("mypoint");
IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
for (int i = 0; i < elements.length; i++) {
try {
(License)elements[i].createExecutableExtension("class");
// ..... Read any other items you need....
}
catch(LicenceException e){
// Plugin is invalid, do not use
}
}

Related

.NET ETW - Manifest file not generated

doing logging component using .NET 4.5
working to log into event log, using ETW
4.5 did include ETW framework into System.Diagnostic.Tracing.*
however samples and external project lead to install Microsft.Diagnostic.Tracing.*
it's really confusing. But for testing purposes, I'm sticking to Microsoft.*
RegisterEvent tool is installed, and attached to the class library containing the custom EventSource, build is good, but I can't see the manifest file (.man) being generated
I'm lost. afaik, I need that .man for manual registration, only then event log will spew out my magic
my custom EventSource is named exactly "EventSource", need to rename to something else like "OMGEventSource"
while trying to fix the initial issue, I switched to using System.Diagnostic.Tracing
however, it's Event class doesn't have Channel property, which is needed by the RegisterEvent tool to generate the man file
have to switch back to use Microsoft.*
in short, forget about System.Diagnostic.Tracing, just stick to Microsoft.*

How can I access one Eclipse RAP entry point from another?

I have an Eclipse RAP 2.3 application with two entry points, say /first and /second.
In the GUI of the first entry point, there is a button with which I would like to open the second entry point in a new browser tab. The event handler of that button is currently
UrlLauncher launcher = RWT.getClient().getService( UrlLauncher.class );
launcher.openURL( "/second");
This already doesn't work when the application is deployed as myapp.war in a Tomcat web server (should then be /myapp/second).
My questions:
What's the best way to determine the URL to open within the event handler?
Do I have to fetch the HttpServletRequest, get the context path and so some string manipulation?
Is it actually safe to call RWT.getRequest() at this point?
Update
According to RĂ¼diger's comment I can acquire the context path in two different ways.
The first approach is
RWT.getRequest().getContextPath();
where RWT.getRequest() is documented with
This method is not recommended
Secondly, I could obtain it with
ApplicationContextImpl ac = (ApplicationContextImpl) RWT.getApplicationContext();
String contextPath = ac.getServletContext().getContextPath();
where the IDE displays the warning
Discouraged access: The type ApplicationContextImpl is not accessible due to restriction on required library ...\org.eclipse.rap.rwt_2.3.2.20150128-1013.jar
Despite the warning, it still works when deploying a WAR file with OSGi bundles to Tomcat.
So, in both cases there is some kind of warning, which makes the solutions look rather like workarounds.
Using RWT.getRequest() is not recommended because usually RWT would shield you from the lower-level servlet API and certain direct interactions with the request could even interfere with RWTs life cycle and yield funny responses.
While in your case it would be safe to access the ServletContext via RWT.getRequest(), I recommend to use
RWT.getUISession( display ).getHttpSession().getServletContext();
to access the servlet context.
The second approach accesses internal classes that aren't part of the public API and therefore shouldn't be use. The accessed classes may change or be (re)moved in the future without further notice and break your application.

Managing an iphone app from another app

We have an architecture where we have a library that we use to automate the application A, which is closely coupled with the app. (Directly linked within A). We had to write a wrapper around the library for customizations within A.
Now we want to separate the library from the application A's code and port wrapper out of A.
For this, we thought of creating a workspace and managing multiple projects there.
Now, the part where I am stuck is, I have to write an app B that links this library and application A. All the wrapper code we wrote for A should reside in this app B. None of the code should reside in the A's repository. B can be anything, that helps Automate A without effecting A's repository. A will have no reference of library / B.
Is there any way we can do it?
Can we do this by making B as a plugin for A? If so, is there any way to support this? I am very new to this, so any kind of guidance is greatly appreciated.
PS: I do not want to launch an app from other. Instead, I want an app to be running, and a way to manipulate it via external source than the application itself.
If any information is missing, please let me know.
Thanks,
RKS
You can register a custom URL scheme in application A.
In application B simply call [[UIApplication sharedApplication] openUrl:myURL].
Finally application A get called through application:handleOpenURL:
See also:
Communicating with Other Apps
URL scheme index
Finally figured out a way to do this. Here is how it goes:
Workspace:
* Generic library
* Application Code
* Library overriding Application specific code, where all the extensions / additions reside.
Scheme:
Created a scheme for the workspace, with following settings:
* Application Specific library with Generic library added as a dependent build
* Application Code having BOTH libraries added as dependent.
It works Wonders!!! :)

How could I include a plugin system for my Dart app?

I have a Qt application containing a Webkit module and using Dart (compiled to JS). It's like a bare-bones browser written in Qt. The application basically replaces certain text on the webpage with different text. I want users to be able to make their own Dart files to replace their own text with their own different text.
Any recommendations for approaches to creating a plugin system?
I think that this question needs a little clarification: are you asking about using Dart for scripting Qt applications (where Dart plays the role of a scripting language), or are you asking about a plugin system for Dart application that is compiled to JS and used in a Qt application, probably via QtScript (in which case, the role of a scripting language is played by JavaScript)?
I presume that it is the latter variant (and I don't know enough about Qt to be able to answer about the former variant anyway).
Let's assume that all plugins for the Dart application are available at the build time of that Qt application, so that you don't need to compile Dart to JS dynamically. Then, if you compile a Dart script, resulting JS will include all necessary code from its #imports. All you need is to create a proper script that imports all plugins and calls them (importing isn't enough, as dead code will be eliminated).
Maybe an example will be more instructive. Let's say that you want to allow plugins to do some work on a web page. One way you might structure it is that every plugin will be a separate #library with a top-level function of a well known name (say doWork). Example of a plugin:
// my_awesome_plugin.dart
#library('My Awesome Plugin')
doWork(page) {
page.replaceAll('JavaScript is great', 'Dart is great');
}
You can have as many plugins of this nature as you wish. Then, you would (at the build time) generate a following simple main script in Dart:
// main.dart
// these lines are automatically generated -- for each plugin file,
// one #import with unique prefix
#import('my_awesome_plugin.dart', prefix: 'plugin1');
#import('another_plugin.dart', prefix: 'plugin2');
main() {
var page = ...; // provided externally, from your Qt app
// and these lines are automatically generated too -- for each plugin,
// call the doWork function (via the prefix)
plugin1.doWork(page);
plugin2.doWork(page);
}
Then, if you compile main.dart to JavaScript, it will include all those plugins.
There are other possibilities to structure the plugin system: each plugin could be a class implementing a specific interface (or inheriting from a specific base class), but the general approach would be the same. At least the approach that I would recommend -- making each plugin a separate library.
You probably don't like the step with generating the main script automatically, and I don't like it either. But currently, Dart only allows one way to dynamically load new code: spawning new isolates. I'm not sure how (or even if) that would work in QtScript, because isolates are implemented as web workers when compiled to JavaScript, so I won't discuss this here.
Things will get more complicated if you want to support compiling Dart scripts at the runtime of your Qt application, but I think that I'm already guessing too much about your project and I might be writing about something you don't really need. So I'll finish it like this for now.

Disable Installed Software & Installation History tab on Help | About | Installation Details

Is there some way I can suppress or disable the "Installed Software" & "Installation History" tabs on Help | About | Installation Details button in a RCP?
I'm not using P2 for this particular application so there will never be any history and the installed software tab has no content.
If you do not want these do show then make sure that the following plug-ins are not deployed in your application's target platform:
org.eclipse.p2.ui
org.eclipse.p2.ui.discovery
org.eclipse.p2.ui.sdk
org.eclipse.p2.ui.updatechecker
Strictly speaking you only really need to remove the first bundle in the above list as the subsequent bundles depend on the core ui bundle. Typically, if I do not want the user to shcedule updates etc. I'll only inlcude the first bundle above. I then build a custom UI around p2 functionality whilst re-using some of the provided core p2 UI API (but without auto-scheduling UI etc. included).
If you want to remove the preference pages for the p2 sheduling/updates, then in your in your WorkbenchAdvisor you can use write the following in the postStartup() method:
PreferenceManager pm =
PlatformUI.getWorkbench(
).getPreferenceManager();
pm.remove("org.eclipse.equinox.internal.p2.ui.sdk.ProvisioningPreferencePage"); pm.remove("org.eclipse.update.internal.ui.preferences.MainPreferencePage");
I ended up deleting the org.eclipse.p2.ui plugin's & features from my built product.
Not the most elegant solution, but it works.
subclass the AboutDialog class and override the createButtonsForButtonBar(Composite) method :)
and use your own InstallationDialog subclass.
to avoid displaying the tabs you don't want you have to override the createFolderItems method.
give a look the loadElements method to understand how this part of the dialog works.