Eclipse: Within a plug-in, how to access another plug-ins preference store? - eclipse-plugin

I have an Eclipse plug-in with a checkbox in the plug-in's preference page.
This checkbox is used for enabling and disabling an editor, which is being launched from this plug-in.
However, the problem is, I would also like to be able to enable and disable this 'editor-launch' from another plug-in, by having actions which change the value of the checkbox in the above mentioned preference page.
Here's the problem, how do I access that local preference store from another plug-in?
I've tried things like..
View myView = (View) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("ViewID");
But this 'myView' always seems to be null.. And also, what would I do with the view since it's the Plug-in I want.
Platform.getBundle('bundleName')...
Same here, want the Plugin, not the bundle corresponding to is.
No matter what I try nothing seems to work.
Does anyone have any ideas?

There are two ways of doing this:
Please refer to http://www.vogella.com/tutorials/EclipsePreferences/article.html#preferences_pluginaccess
Using .getPluginPreferences(). For example, there is a plugin class "com.xxx.TestPlugin" which extends org.eclipse.ui.plugin.AbstractUIPlugin.Plugin, in order to get access to the preferences of TestPlugin. The plugin code could be below:
public class TestPlugin extends AbstractUIPlugin {
private static TestPlugin plugin;
public static final String PREF_TEST = "test_preference";
/**
* The constructor.
*/
public TestPlugin() {
plugin = this;
}
/**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
plugin = null;
}
/**
* Returns the shared instance.
*/
public static TestPlugin getDefault() {
return plugin;
}
}
To access the preference of TestPlugin, the code could be:
TestPlugin.getDefault().getPluginPreferences().getDefaultBoolean(TestPlugin.PREF_TEST);

Or have a look at this answer: Writing Eclipse plugin to modify Editor Preferences

This thread recommend the use of a Service tracker:
ServiceTracker tracker = new ServiceTracker(ToolkitPlugin.getDefault().getBundle().getBundleContext(),
IProxyService.class.getName(), null);
tracker.open();
proxyService = (IProxyService) tracker.getService();
proxyService.addProxyChangeListener(this);

This may work.
Prefs stores are found per plugin. This is one way to get a prefs store for the plugin whose activator class is ActivatorA.
IPreferenceStore store = ActivatorA.getDefault().getPreferenceStore();
If you want another plugin to refer to the same store, perhaps you could expose some api on ActivatorA for it to get there, e.g.
public IPreferenceStore getSharedPrefs() {
return ActivatorA.getDefault().getPreferenceStore();
}
The second plugin would find the shared store by doing this
IPreferenceStore sharedPrefs = ActivatorA.getSharedPrefs();
Good luck.

Related

How to enable module in Orchard migration?

I want to enable a specific module in a migration but the module is not enabled immediately.
The issue here seems to be the state of the module, it is set to Rising in table Orchard_Settings_ShellFeatureStateRecord. In this case I cannot enable the module manually in Admin anymore, I need to restart the web server after the migration has been executed to get the module to state Up.
The migration code looks like
public class Migration: Orchard.Data.Migration.DataMigrationImpl
{
// public
public Migration(Orchard.Environment.Features.IFeatureManager aFeatureManager)
{
mFeatureManager = aFeatureManager;
}
...
public int UpdateFrom1()
{
System.Collections.Generic.Dictionary<string, Orchard.Environment.Extensions.Models.FeatureDescriptor> lFeatures =
mFeatureManager.GetAvailableFeatures().ToDictionary(m => m.Id, m => m);
if (lFeatures.ContainsKey("Orchard.Taxonomies"))
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"}, true);
...
}
// private
private readonly Orchard.Environment.Features.IFeatureManager mFeatureManager;
}
I also tried using IModuleManager, did not work. Then I tried enabling another simple feature like Orchard.Alias.UI, did not work either.
Is this intended behavior or what might be wrong in the code?
If your feature has a dependency on taxonomies, enabling it will also enable taxonomies. You don't need to do anything else. That is, unless the dependency is something new that you're adding with the new version. In that case, I'd probably display a warning asking the user to enable it, and I'd make the code resilient to taxonomies not being enabled (which is a good idea no matter what)
Change this line:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"},true);
to this one:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"});

CRM 2011 - ITracingService getting access to the traceInfo at runtime

I have some custom logging in my plugin and want to include the contents of my tracingService in my custom logging (which is called within a catch block, before the plugin finishes).
I cant seem to access the content of tracingService. I wonder if it is accessible at all?
I tried tracingService.ToString() just incase the devs had provided a useful overload, alas as expected I get name of the class "Microsoft.Crm.Sandbox.SandboxTracingService".
Obviously Dynamics CRM makes use of the tracingService content towards the end of the pipeline if it needs to.
Anybody have any ideas on this?
Kind Regards,
Gary
The tracing service does not provide access to the trace text during execution but that can be overcome by creating your own implementation of ITracingService. Note, you cannot get any text that was written to the trace log prior to the Execute method of your plugin being called - meaning if you have multiple plugins firing you won't get their trace output in the plugin that throws the exception.
public class CrmTracing : ITracingService
{
ITracingService _tracingService;
StringBuilder _internalTrace;
public CrmTracing(ITracingService tracingService)
{
_tracingService = tracingService;
_internalTrace = new StringBuilder();
}
public void Trace(string format, params object[] args)
{
if (_tracingService != null) _tracingService.Trace(format, args);
_internalTrace.AppendFormat(format, args).AppendLine();
}
public string GetTraceBuffer()
{
return _internalTrace.ToString();
}
}
Just instantiate it in your plugin passing in the CRM provided ITracingService. Since it is the same interface it works the same if you pass it to other classes and methods.
public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var tracingService = new CrmTracing((ITracingService)serviceProvider.GetService(typeof(ITracingService)));
tracingService.Trace("Works same as always.");
var trace = tracingService.GetTraceBuffer();
}
}
To get the traceInfo string from traceService at runtime I used debugger to interrogate the tracingService contents.
So the trace string is accessible from these expressions...
for Plugins
((Microsoft.Crm.Extensibility.PipelineTracingService)(tracingService)).TraceInfo
for CWA
((Microsoft.Crm.Workflow.WorkflowTracingService)(tracingService)).TraceInfo
You can drill into the tracing service by debugging and extract the expression.
However, at design time neither of these expressions seem to be accessible from any of the standard CRM 2011 SDK dlls... so not sure if its possible as yet.

How do I get Xtext's model from a different plugin?

I've written an Xtext-based plugin for some language. I'm now interested in creating a new independent view (as a separate plugin, though it requires my first plugin), which will interact with the currently-active DSL document - and specifically, interact with the model Xtext parsed (I think it's called the Ecore model?). How do I approach this?
I saw I can get an instance of XtextEditor if I do something like this when initializing my view:
getSite().getPage().addPartListener(new MyListener());
And then, in MyListener, override partActivated and partInputChanged to get an IWorkbenchPartReference, which is a reference to the XtextEditor. But what do I do from here? Is this even the right approach to this problem? Should I instead use some notification functionality from the Xtext side?
Found it out! First, you need an actual document:
IXtextDocument doc = editor.getDocument();
Then, if you want to access the model:
doc.modify(new IUnitOfWork.Void<XtextResource>() { // Can also use just IUnitOfWork
#Override public void process(XtextResource state) throws Exception {
...
}
});
And if you want to get live updates whenever it changes:
doc.addModelListener(new IXtextModelListener() {
#Override public void modelChanged(XtextResource resource) {
for (EObject model : resource.getContent()) {
...
}
}
});

Change application.conf runtime?

I want to set the database connection at run time for my Play project. I know that I can set a property run time with the following code:
#OnApplicationStart public class Bootstrap extends Job
{
#Override public void doJob()
{
// now set the values in the properties file
Play.configuration.setProperty("db.driver", dbDriver);
Play.configuration.setProperty("db.url", dbUrl);
Play.configuration.setProperty("db.user", dbUsername);
Play.configuration.setProperty("db.pass", dbPassword);
}
}
But when executing the code above the file is not actually changed, I think just in memory.
How can I set the database properties and force Play! to use this properties in order to connect to the right database onApplicationStart?
Thanks!
UPDATE 2012-01-29
Solution is possible via a plugin. In this plugin I have to override onConfigurationRead() and apply the properties to the configuration file at that moment. I will try to post some code as soon as I have time for this.
By the time you change the properties, the DB plugin is already initialized. You need to write a plugin and overwrite the onConfigurationRead() method, then put your new settings there. Paly's dbplugin will init later on.
I faced with the necessity of programmatically obtaining values from aws secret manager in runtime before using that values in play framework configuration. You can override initial default values from application.conf and add new.
Work for play framework v2.7.3
import com.typesafe.config.ConfigValueFactory;
import play.api.Configuration;
import play.api.inject.guice.GuiceApplicationBuilder;
import play.api.inject.guice.GuiceApplicationLoader;
public class ExtendedGuiceApplicationLoader extends GuiceApplicationLoader {
#Override
public GuiceApplicationBuilder builder(Context context) {
Configuration configuration = new Configuration(
context.initialConfiguration().underlying()
.withValue("db.default.username",
ConfigValueFactory.fromAnyRef("aws.secret.db.username"))
.withValue("db.default.password",
ConfigValueFactory.fromAnyRef("aws.secret.db.password"))
);
return super.builder(
new Context(context.environment(),
configuration,
context.lifecycle(),
context.devContext())
);
}
}
DonĀ“t forget add this string to application.conf
play.application.loader="youpackage.ExtendedGuiceApplicationLoader"
Are you sure this is what you really intend to do?
Play offers the possibility to add different configurations in your application.conf
for example you could have:
db.url=mydefaulturl
%uat.db.url=uaturl
%prod.db.url=produrl
%prod1.db.url=prod1url
And then start the app with play start --%uat or play start --%prod

Attach my action to F5/Refresh

i'm writing a plugin for Eclipse and i would like to attach one of my actions to Eclipse F5/Refresh event.
Can anyone help me?
Thanks!
You can attach a IExecutionListener to the ICommandService. You will get notification of all the commands executed. You can look for the command id that you want (in this case org.eclipse.ui.file.refresh) and do your operation
I'm assuming you're writing this for Eclipse Helios (3.6).
In Eclipse help, in the Platform Plug-in Developer Guide -> Programmer's Guide -> Advanced resource concepts -> Refresh providers, there's an extension point.
org.eclipse.core.resources.refreshProviders
Your class has to extend RefreshProvider to use this extension.
According to Prakash G. R., I show the sample code.
Because the initialization code in Activator does not work if we need to use Workbench, therefore I use the startup extension point. The plugin.xml is
<extension
point="org.eclipse.ui.startup">
<startup
class="sampleplugin.MyStartUp">
</startup>
</extension>
Therefore in MyStartUp class we add the ExecutionListener to ICommandService.
The important thing is that the ExecutionEvent in the preExecute method is not able to
extract the selection. This is different from usual ExecutionEvent in Command.
Therefore , the MyStartUp.java is
public class MyStartUp implements IStartup {
#Override
public void earlyStartup() {
ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService .class);
service.addExecutionListener(
new IExecutionListener() {
...
#Override
public void postExecuteSuccess(String commandId,
Object returnValue) {
// do something post
}
#Override
public void preExecute(String commandId,
final ExecutionEvent event) {
if (org.eclipse.ui.IWorkbenchCommandConstants.FILE_REFRESH.equals(commandId) ) {
IWorkbench wb = PlatformUI.getWorkbench();
IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
IWorkbenchPage page = win.getActivePage();
ISelection selection = page.getSelection();
// do something using selection
}
}
});
}
}
I use the
IWorkbench wb = PlatformUI.getWorkbench();
IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
IWorkbenchPage page = win.getActivePage();
ISelection selection = page.getSelection();
instead of
IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event);
because the above reason. However, this is due to the Eclipse inner mechanism.
The refresh event uses an old action mechanism and The ExternalActionManager call
preExecute method directly in which the event has no data for selection.
I want the second formula
IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event);
may be available in preExecute method in the future.