How to access an compatibility layer IViewPart’s (e4) MPart - eclipse-plugin

I am porting an existing Eclipse plug-in to e4. From within a non-ported IViewPart I would like to access the view’s corresponding e4 MPart but couldn’t get the following to work reliably:
EPartService partService = (EPartService) PlatformUI.getWorkbench().getService(EPartService.class);
MPart part = partService.findPart(getSite().getId());
Placed in createPartControlComposite)
I sometimes get an IllegalStateException (“Application does not have an active window“).

Avoid using the part service from the workbench as this only works when there is an active window.
Instead use the part service for the current window (which might not be active). You can get this in the IViewPart using:
EPartService partService = getSite().getService(EPartService.class);
MPart part = partService.findPart(getSite().getId());

Related

PyDev custom code complete plug-in only detects every other key stroke

I have an Eclipse plug-in that I created to add Code Completion entries. I configured Eclipse to automatically show code completion as I type (Windows | Preferences | PyDev | Editor | Code Completion | Request completion on all letter chars and '_'?). At first when I typed I kept getting the templates showing instead of my code completion entries, so I removed all the templates ( Windows | Preferences | PyDev | Templates --selected all, then "Remove"). Now when I type it works properly for every other key pressed. For example, when I type 'print', the code completion list drops down with my entries as expected when I press 'p'. However, when I press 'r', the list disappears. When I press 'i' the list shows again, but disappears when I press the next key ('n'), etc. Is this a Pydev defect, or am I doing something wrong? It works fine for the templates and other default code completion, just not for my plug-in. Here is a code snipped of a watered down version of my code:
//...
public class MyPlugin implements IPyDevCompletionParticipant
#Override
public Collection<Object> getGlobalCompletions(CompletionRequest arg0,
ICompletionState arg1) throws MisconfigurationException {
String replacementString = "{" + arg0.qualifier + "}";
int replacementOffset = arg0.documentOffset - arg0.qlen;
int replacementLength = arg0.qlen;
int cursorPosition = arg0.documentOffset;
String displayString = arg0.qualifier;
final IContextInformation contextInformation = new ContextInformation(
"displayStr", "message");
String additionalProposalInfo = "additionalProposalInfo";
final String bundle = "com.github.EclipseChameleonPlugins";
final org.eclipse.swt.graphics.Image image = new org.eclipse.swt.graphics.Image(getDisplay(), locateFile(bundle, "icons/smiley.gif").getPath());
arg0.showTemplates = false;
final CompletionProposal proposal = new CompletionProposal(
replacementString, replacementOffset, replacementLength,
cursorPosition, image, displayString, contextInformation, additionalProposalInfo);
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
// ADD IT...
proposals.add(proposal);
final Collection<Object> returnProposals = new ArrayList<Object>(
proposals);
return returnProposals;
}
I have searched Google and StackOverflow, and have seen very little about code development for PyDev plug-ins, and nothing that mentions or addresses this issue.
Here are a few of the links I have looked at, but none have answered my question:
Auto-completion in PyDev
Code completion for custom modules not working with PyDev
pydev remote debuging - code completion in interactive console?
Well, plain PyDev behaves as expected for me (i.e.: the code completions appear on all the key strokes).
Now, let's see if we can track it down a bit better:
instead of removing the templates, what you should do is go to the preferences > pydev > editor > code completion (ctx insensitive and common tokens) and disable the 'use common tokens auto code completion?'.
The reference code for you to follow is: com.python.pydev.codecompletion.participant.ImportsCompletionParticipant and com.python.pydev.codecompletion.ctxinsensitive.CtxParticipant (i.e.: the IPyDevCompletionParticipant interface -- as you're doing already)
I think the main issue you're having is because you're not implementing the additional extensions for completions (to validate its context and keep it there) -- either you can make your own subclass of org.python.pydev.editor.codecompletion.AbstractPyCompletionProposalExtension2 or you can use org.python.pydev.editor.codecompletion.PyLinkedModeCompletionProposal (just constructing it with the proper parameters -- I believe it supports having a null IToken -- and you can pass an image to it which will be used if the token is null).
You should probably not mess with the CompletionRequest at that point (when it gets there to an extension it should be considered immutable -- even if it's not in reality).

Broken WF4 workflow rehydration

Consider a WF4 project running in IIS, with a single workflow definition (xamlx) and a SqlInstanceStore for persistence.
Instead of hosting the xamlx directly, we host a WorkflowServiceHostFactory which spins up a dedicated WorkflowServiceHost on a seperate endpoint for every customer.
This has been running fine for a while, until we required a new version of the workflow definition, so now on top of Flow.xamlx I have Flow1.xamlx.
Since all interactions with the workflow service are wrapped with business logic which is smart enough to identify the required version, this homebrew versioning works fine for newly started workflows (both on Flow.xamlx and Flow1.xamlx).
However, workflows started before this change fail to be reactivated (on a post the servicehost throws an UnknownMessageReceived exception).
Since WF isn't overly verbose in telling you WHY it can't reactivate the workflow (wrong version, instance not found, lock, etc), we attached a SQL profiler to the database.
It turns out the 'WorkflowServiceType' the WorkflowServiceHost uses in its queries is different from the stored instances' WorkflowServiceType. Likely this is why it fails to detect the persisted instance.
Since I'm pretty sure I instance the same xamlx, I can't understand where this value is coming from. What parameters go into the calculation of this Guid, does the environment matter (sitename), and what can I do to reactivate the workflow ?
In the end I decompiled System.Activities.DurableInstancing. The only setter for WorkflowHostType on SqlWorkflowInstanceStore was in ExtractWorkflowHostType:
private void ExtractWorkflowHostType(IDictionary<XName, InstanceValue> commandMetadata)
{
InstanceValue instanceValue;
if (commandMetadata.TryGetValue(WorkflowNamespace.WorkflowHostType, out instanceValue))
{
XName xName = instanceValue.Value as XName;
if (xName == null)
{
throw FxTrace.Exception.AsError(new InstancePersistenceCommandException(SR.InvalidMetadataValue(WorkflowNamespace.WorkflowHostType, typeof(XName).Name)));
}
byte[] bytes = Encoding.Unicode.GetBytes(xName.ToString());
base.Store.WorkflowHostType = new Guid(HashHelper.ComputeHash(bytes));
this.fireRunnableInstancesEvent = true;
}
}
I couldn't clearly disentangle the calling code path, so I had to find out at runtime by attaching WinDbg/SOS to IIS and breaking on HashHelper.ComputeHash.
I was able to retreive the XName that goes into the hash calculation, which has a localname equal to the servicefile, and a namespace equal to the [sitename]/[path]/.
In the end the WorkflowHostType calculation comes down to:
var xName = XName.Get("Flow.xamlx.svc", "/examplesite/WorkflowService/1/");
var bytes = Encoding.Unicode.GetBytes(xName.ToString());
var WorkflowHostType = new Guid(HashHelper.ComputeHash(bytes));
Bottomline: apparently workflows can only be rehydrated when the service filename, sitename and path are all identical (case sensitive) as when they were started

MsTest, DataSourceAttribute - how to get it working with a runtime generated file?

for some test I need to run a data driven test with a configuration that is generated (via reflection) in the ClassInitialize method (by using reflection). I tried out everything, but I just can not get the data source properly set up.
The test takes a list of classes in a csv file (one line per class) and then will test that the mappings to the database work out well (i.e. try to get one item from the database for every entity, which will throw an exception when the table structure does not match).
The testmethod is:
[DataSource(
"Microsoft.VisualStudio.TestTools.DataSource.CSV",
"|DataDirectory|\\EntityMappingsTests.Types.csv",
"EntityMappingsTests.Types#csv",
DataAccessMethod.Sequential)
]
[TestMethod()]
public void TestMappings () {
Obviously the file is EntityMappingsTests.Types.csv. It should be in the DataDirectory.
Now, in the Initialize method (marked with ClassInitialize) I put that together and then try to write it.
WHERE should I write it to? WHERE IS THE DataDirectory?
I tried:
File.WriteAllText(context.TestDeploymentDir + "\\EntityMappingsTests.Types.csv", types.ToString());
File.WriteAllText("EntityMappingsTests.Types.csv", types.ToString());
Both result in "the unit test adapter failed to connect to the data source or read the data". More exact:
Error details: The Microsoft Jet database engine could not find the
object 'EntityMappingsTests.Types.csv'. Make sure the object exists
and that you spell its name and the path name correctly.
So where should I put that file?
I also tried just writing it to the current directory and taking out the DataDirectory part - same result. Sadly, there is limited debugging support here.
Please use the ProcessMonitor tool from technet.microsoft.com/en-us/sysinternals/bb896645. Put a filter on MSTest.exe or the associate qtagent32.exe and find out what locations it is trying to load from and at what point in time in the test loading process. Then please provide an update on those details here .
After you add the CSV file to your VS project, you need to open the properties for it. Set the Property "Copy To Output Directory" to "Copy Always". The DataDirectory defaults to the location of the compiled executable, which runs from the output directory so it will find it there.

Ninject: More than one matching bindings are available

I have a dependency with parameters constructor. When I call the action more than 1x, it show this error:
Error activating IValidationPurchaseService
More than one matching bindings are available.
Activation path:
1) Request for IValidationPurchaseService
Suggestions:
1) Ensure that you have defined a binding for IValidationPurchaseService only once.
public ActionResult Detalhes(string regionUrl, string discountUrl, DetalhesModel detalhesModel)
{
var validationPurchaseDTO = new ValidationPurchaseDTO {...}
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
...
}
I'm not sure what are you trying to achieve by the code you cited. The error is raised because you bind the same service more than once, so when you are trying to resolve it it can't choose one (identical) binding over another. This is not how DI Container is supposed to be operated. In your example you are not getting advantage of your DI at all. You can replace your code:
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
With this:
this.ValidationPurchaseService = new ValidationPurchaseService(validationPurchaseDTO:validationPurchaseDTO, confirmPayment:true)
If you could explain what you are trying to achieve by using ninject in this scenario the community will be able to assist further.
Your KernelFactory probably returns the same kernel (singleton) on each successive call to the controller. Which is why you add a similar binding every time you hit the URL that activates this controller. So it probably works the first time and starts failing after the second time.

Getting Path (context root) to the Application in Restlet

I am needing to get the application root within a Restlet resource class (it extends ServerResource). My end goal is trying to return a full explicit path to another Resource.
I am currently using getRequest().getResourceRef().getPath() and this almost gets me what I need. This does not return the full URL (like http://example.com/app), it returns to me /resourceName. So two problems I'm having with that, one is it is missing the schema (the http or https part) and server name, the other is it does not return where the application has been mounted to.
So given a person resource at 'http://dev.example.com/app_name/person', I would like to find a way to get back 'http://dev.example.com/app_name'.
I am using Restlet 2.0 RC3 and deploying it to GAE.
It looks like getRequest().getRootRef().toString() gives me what I want. I tried using a combination of method calls of getRequest().getRootRef() (like getPath or getRelativePart) but either they gave me something I didn't want or null.
Just get the base url from service context, then share it with the resources and add resource path if needed.
MyServlet.init():
String contextPath = getServletContext().getContextPath();
getApplication().getContext().getAttributes().put("contextPath", contextPath);
MyResource:
String contextPath = getContext().getAttributes().get("contextPath");
request.getRootRef() or request.getHostRef()?
The servlet's context is accessible from the restlet's application:
org.restlet.Application app = org.restlet.Application.getCurrent();
javax.servlet.ServletContext ctx = ((javax.servlet.ServletContext) app.getContext().getAttributes().get("org.restlet.ext.servlet.ServletContext"));
String path = ctx.getResource("").toString();